I’m currently trying to make my application using some Async methods. All my IO is done through explicit implementations of an interface and I am a bit confused about how to make the operations async.
As I see things I have two options in the implementation:
interface IIO
{
void DoOperation();
}
OPTION1: Do an implicit implementation async and await the result in the implicit implementation.
class IOImplementation : IIO
{
async void DoOperation()
{
await Task.Factory.StartNew(() =>
{
//WRITING A FILE OR SOME SUCH THINGAMAGIG
});
}
#region IIO Members
void IIO.DoOperation()
{
DoOperation();
}
#endregion
}
OPTION2: Do the explicit implementation async and await the task from the implicit implementation.
class IOAsyncImplementation : IIO
{
private Task DoOperationAsync()
{
return new Task(() =>
{
//DO ALL THE HEAVY LIFTING!!!
});
}
#region IIOAsync Members
async void IIO.DoOperation()
{
await DoOperationAsync();
}
#endregion
}
Are one of these implementations better than the other or is there another way to go that I am not thinking of?
Neither of these options is correct. You're trying to implement a synchronous interface asynchronously. Don't do that. The problem is that when
DoOperation()
returns, the operation won't be complete yet. Worse, if an exception happens during the operation (which is very common with IO operations), the user won't have a chance to deal with that exception.What you need to do is to modify the interface, so that it is asynchronous:
This way, the user will see that the operation is
async
and they will be able toawait
it. This also pretty much forces the users of your code to switch toasync
, but that's unavoidable.Also, I assume using
StartNew()
in your implementation is just an example, you shouldn't need that to implement asynchronous IO. (Andnew Task()
is even worse, that won't even work, because you don'tStart()
theTask
.)Better solution is to introduce another interface for async operations. New interface must inherit from original interface.
Example:
P.S. Redesign your async operations so they return Task instead of void, unless you really must return void.