nak*_*iya 5 c# task-parallel-library async-await
我有很多像这样的代码:
var feed = new DataFeed(host, port);
feed.OnConnected += (conn) =>
{
feed.BeginLogin(user, pass);
};
feed.OnReady += (f) =>
{
//Now I'm ready to do stuff.
};
feed.BeginConnect();
Run Code Online (Sandbox Code Playgroud)
如您所见,我使用通常的异步操作方式.如何更改此代码才能使用async await?最好是这样的:
public async void InitConnection()
{
await feed.BeginConnect();
await feed.BeginLogin(user, pass);
//Now I'm ready
}
Run Code Online (Sandbox Code Playgroud)
Ser*_*kiy 10
您可以使用TaskCompletionSource<T>将EAP(基于事件的异步模式)包装到Tasks中.目前尚不清楚如何处理DataFeed类中的错误和取消操作,因此您需要修改此代码并添加错误处理(示例):
private Task ConnectAsync(DataFeed feed)
{
var tcs = new TaskCompletionSource<object>();
feed.OnConnected += _ => tcs.TrySetResult(null);
feed.BeginConnect();
return tcs.Task;
}
private Task LoginAsync(DataFeed feed, string user, string password)
{
var tcs = new TaskCompletionSource<object>();
feed.OnReady += _ => tcs.TrySetResult(null);
feed.BeginLogin(user, pass);
return tcs.Task;
}
Run Code Online (Sandbox Code Playgroud)
现在您可以使用以下方法:
public async void InitConnection()
{
var feed = new DataFeed(host, port);
await ConnectAsync(feed);
await LoadAsync(feed, user, pass);
//Now I'm ready
}
Run Code Online (Sandbox Code Playgroud)
注意 - 您可以将这些异步方法移动到DataFeed类.但是,如果您可以修改DataFeed,那么最好使用APM API TaskFactory.FromAsync包装到Tasks.
不幸的是,没有非泛型TaskCompletionSource会返回非泛型,Task所以通常解决方法是使用Task<object>.