Reputation: 3460
I am working with a custom framework wich is used for a long time within my company. I want to use the new async feature within my code.
In order todo this i have to mark the "ProcessRequestMessage" of "MyClass" as async. I can't change the interface "IFramework" and class "FrameworkBase".
The Framework expects already that "ProcessRequestMessage" finishes asynchronously so i don't have to use "Wait()" on the End of the method. A call to "SetResponseCode" signalizes to the framework to finalize the instance of "MyClass"
Question: I read in the documentation of the async feature that only void Events should be marked as async for Entry into the async workflow (Task does not apply here). My code requires that i mark the implementation of a void interface method as Entry point.
So can i do this:
interface IFramework
{
void ProcessRequestMessage()
void SetResponseCode(int code)
}
public abstract class FrameworkBase: IFramework
{
abstract void ProcessRequestMessage()
public void SetResponseCode(int code)
{
//internal implementation
}
}
public class MyClass: FrameworkBase
{
protected override async void ProcessRequestMessage()
{
//await something
SetResponseCode(0);
}
}
Upvotes: 1
Views: 518
Reputation: 456887
There are two major reasons why you should avoid async void
:
In your particular case, the calling code does not assume the operation has completed when ProcessRequestMessage
returns, so you can use async void
but you must be very careful with your exceptions. (I prefer using task continuations instead of async void
).
I recommend writing a FrameworkTaskBase
just for this:
public class FrameworkTestBase: FrameworkBase
{
protected abstract Task ProcessRequestMessageAsync();
protected override sealed void ProcessRequestMessage()
{
ProcessRequestMessageAsync().ContinueWith(t =>
{
if (t.IsFaulted || t.IsCanceled)
SetResponseCode(-1);
else
SetResponseCode(0);
});
}
}
public class MyClass: FrameworkBase
{
protected override async Task ProcessRequestMessageAsync()
{
//await something
}
}
Alternatively (using async void
):
public class FrameworkTestBase: FrameworkBase
{
protected abstract Task ProcessRequestMessageAsync();
protected override sealed async void ProcessRequestMessage()
{
try
{
await ProcessRequestMessageAsync();
SetResponseCode(0);
}
catch
{
SetResponseCode(-1);
}
}
}
Upvotes: 3