我会使用一个TaskCompletionSource<T>
来封装可以从Host.Login
触发的事件,并将其作为Host
类型周围的扩展方法:
public static class HostExtensions
{
public static Task<bool> LoginAsync(this Host host, APIServerType serverType, string name, string id)
{
var tcs = new TaskCompletionSource<bool>();
try
{
host.LoginSuccess += (object obj, LoginSuccessEventHandler e) =>
{
tcs.SetResult(true);
}
host.LoginFailure += (object obj, LoginFailureEventHandler e) =>
{
tcs.SetResult(false);
}
}
catch (Exception e)
{
tcs.SetException(e);
}
host.Login(serverType, name, id);
return tcs.Task;
}
}
如果通知消息很重要,您可以创建一个名为
LoginDetails
的类型,并将其用作
TaskCompletionSource
的返回类型:
public class LoginDetails
{
public bool IsSuccess { get; set; }
public string Notification { get; set; }
}
并像这样使用它:
public static Task<LoginDetails> LoginAsync(this Host host, APIServerType serverType, string name, string id)
{
var tcs = new TaskCompletionSource<LoginDetails>();
var loginDetails = new LoginDetails();
try
{
host.LoginSuccess += (object obj, LoginSuccessEventHandler e) =>
{
loginDetails.IsSuccess = true;
tcs.SetResult(loginDetails);
}
host.LoginFailure += (object obj, LoginFailureEventHandler e) =>
{
loginDetails.IsSuccess = false;
tcs.SetResult(loginDetails);
}
host.Notification += (object obj, NotificationEventHandler e) =>
{
loginDetails.Notificaiton = e.Notification // I assume it would look something like this
tcs.SetResult(loginDetails);
}
}
catch (Exception e)
{
tcs.SetException(e);
}
host.Login(serverType, name, id);
return tcs.Task;
}
现在你可以在
LoginAsync
上使用
await
。
var login = await host.LoginAsync(APIServerType.Simulator, "T4Example", "112A04B0-5AAF-42F4-994E-FA7CB959C60B")
顺便说一句,如果你在Console
应用程序中使用此功能,你需要使用Result
而不是await
(这会将控制权返回给调用者) 在Main
中, 这有点可惜,因为这样就会失去异步调用的全部意义:
var login = host.LoginAsync(APIServerType.Simulator, "T4Example", "112A04B0-5AAF-42F4-994E-FA7CB959C60B").Result