My team and I have a very poor understanding of best practices in relation to telnet. We have Task.Delay
and Task.Wait
in the code, including async
voids and from what I understand those are potential areas that can cause deadlocks and other issues.
I'm trying to understand async
in relation to running a telnet client. Is this a safe implementation of cancellation tokens and telnet connections?
public enum TelnetClientStatus : int
{
Unset = 0,
Connected= 1,
Disconnected = 2,
Failed = 3
}
public TelnetClientStatus Status { get; set; } = TelnetClientStatus.Unset;
public async Task OpenConnection()
{
//Don't allow the session to keep trying to open after the 5 seconds
var cancellationTokenSource = new CancellationTokenSource();
cancellationTokenSource.CancelAfter(TimeSpan.FromSeconds(5));
Status = await Task.Run(MakeConnection, cancellationTokenSource.Token);
}
private async Task<TelnetClientStatus> MakeConnection()
{
_streamSocket = new StreamSocket();
_dataWriter = new DataWriter(_streamSocket.OutputStream);
_dataReader = new DataReader(_streamSocket.InputStream)
{
InputStreamOptions = InputStreamOptions.Partial
};
try
{
await _streamSocket.ConnectAsync(new HostName(HostName), Port.ToString());
return TelnetClientStatus.Connected;
}
catch (TaskCanceledException) //All other exceptions need to be investigated not ignored
{
//I understand a connection failed due to timeout, give the app some flag to work with
//Maybe retry the connection?
return TelnetClientStatus.Failed;
}
catch (Exception ex)
{
throw ex;
}
}
1 Answer 1
I see at least two points.
if you have a
catch
to catch a sytemException
(wich is not good btw., it would be better to catch specific exceptions) and the only action is tothrow
that exception then its useless to have. If you need to rethrow an exception you should always omit theex
so justthrow;
, otherwise theStackTrace
will be broken.Having the
public
setter of theStatus
property is breaking encapsulation. Why should a user of the object be able to set this property? You should make itprivate
.
-
\$\begingroup\$ Unfortunately the exception that gets thrown is actually of type system exception and I have no way of being more specific. \$\endgroup\$C Bauer– C Bauer2015年12月22日 03:13:14 +00:00Commented Dec 22, 2015 at 3:13
-
\$\begingroup\$ @CBauer - Then don't catch it. If you can't handle an exception, don't try. \$\endgroup\$Bobson– Bobson2015年12月22日 16:56:07 +00:00Commented Dec 22, 2015 at 16:56
-
\$\begingroup\$ @Bobson What do you mean? The exception is a generic async error of type
System.Exception
and occurs when one async call returns before a previous call due to network latency. The right thing to do in that situation is to ignore the response from the earlier call. \$\endgroup\$C Bauer– C Bauer2015年12月22日 17:03:00 +00:00Commented Dec 22, 2015 at 17:03 -
\$\begingroup\$ @CBauer - If the right thing to do is ignore it, then you should swallow the error with a comment explaining why (like you do with
TaskCanceledException
). You don't have to catchException
as the last thing in yourtry/catch
block. Either do something with it or don't catch it. Never just catch and rethrow without a very specific reason. \$\endgroup\$Bobson– Bobson2015年12月22日 21:15:09 +00:00Commented Dec 22, 2015 at 21:15 -
\$\begingroup\$ Wires crossed my mistake I was thinking of different code! I have removed the errant catch from the code. \$\endgroup\$C Bauer– C Bauer2015年12月22日 21:16:41 +00:00Commented Dec 22, 2015 at 21:16