Reputation: 1432
I'm developing an application for monitoring certain tasks (e.g. if certain services/websites are currently up and running, certain records in the database exist, etc.). And as most these tasks are long running, I use TPL
with async/await
.
I have an base class for all such tasks:
public abstract class LongRunningOperation
{
// .. some props...
internal async void Start()
{
try
{
this.Status = OperationStatus.Started;
await this.DoStart();
this.Status = OperationStatus.Finished;
}
catch (Exception e)
{
this.Status = OperationStatus.Error;
this.Message = e.ToString();
}
}
protected abstract Task DoStart();
}
And method that launches these tasks looks like this:
public static LongRunningOperation[] LaunchOperations()
{
LongRunningOperation[] operations = GetAllLongRunningOperations();
foreach (var o in operations)
Task.Factory.StartNew(() => { o.Start(); });
return operations;
}
The array returned by this method is used to monitor all LongRunningOperation
s and log the stats. currently I have a console application having a while (true)
loop that prints out the stats (name, status, current runtime) for each operation on the screen (refreshing every second) until all the operations are finished.
The thing that bothers me is the async void
method. I've read that it's bad practice to use async void
methods, but:
Start
method to return Task
, its return value will never be used anywhere, and I can't think why I need itI'd appreciate it if someone could clarify these points
Upvotes: 2
Views: 2455
Reputation: 2296
An async void
method is a "fire and forget" operation. You can not wait for any result, and will not know when the operation completes and if it has been successful or not.
Basically you should use void when you are sure that you'll never need to know when the operation finished and if the operation execution was successful or not (for example writing logs).
With async methods that return Task
, a caller is capable of waiting for an operation to finish, and also handle exceptions that happened during the execution of the operation.
To summarize, if you do not need a result, an async Task
is slightly better because you can await it as well as handle exceptions and deal with task ordering.
Upvotes: 7