我有以下代码:
static void Main(string[] args)
{
moHost = new Host(
APIServerType.Simulator,
"T4Example",
"112A04B0-5AAF-42F4-994E-FA7CB959C60B",
"CTS",
"myUser",
"myPass"); //automated login
moHost = Host.Login(
APIServerType.Simulator,
"T4Example",
"112A04B0-5AAF-42F4-994E-FA7CB959C60B"); //manual login window
moAccounts = moHost.Accounts;
System.Console.WriteLine(moAccounts.ToString());
}
我知道第一次自动登录是发送的异步请求,我需要等待"对
登录成功将触发:
public event Host.LoginSuccessEventHandler LoginSuccess
登录失败时会触发:
public event Host.LoginFailureEventHandler LoginFailure
通用通知将由以下方式触发:
public event Host.NotificationEventHandler Notification
如何处理此问题并正确等待登录成功或失败?
第一次自动登录尝试没有显示我连接,而第二个手动登录窗口确实成功(因此我可以认为我的凭据很好,现在只是代码没有正确'等待'。)
答案 0 :(得分:5)
我会使用TaskCompletionSource<T>
来封装可以从Host.Login
触发的事件,并将其用作Extension Method
类型周围的Host
:
public static class HostExtensions
{
public static async 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 async 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;
}
现在,您可以在await
上使用LoginAsync
。
var login = await host.LoginAsync(APIServerType.Simulator, "T4Example", "112A04B0-5AAF-42F4-994E-FA7CB959C60B");
另外,如果您在Console
应用程序中使用此功能,则必须使用阻止而不是Result
的{{1}}(其产量)在await
内控制回调用者,这有点遗憾,因为它会错过异步调用的全部内容:
Main