[英]Wait for an async method to return
我有一堂课:
public class User
{
public string id, name, email, image;
public User (IFBGraphUser user)
{
id = user.GetId ();
name = user.GetName ();
GetEmail ();
}
private void GetEmail()
{
FBRequestConnection.StartWithGraphPath ("/me", null, "GET", ConnectionReturn);
}
private void ConnectionReturn(FBRequestConnection connection, NSObject result, NSError error)
{
var me = (FBGraphObject)result;
Console.WriteLine("this is a test");
this.email = me["email"].ToString();
}
}
使用异步方法: StartWithGraphPath
当调用构造函数我想等StartWithGraphPath
之前完成GetEmail
回报。
我该怎么做?
StartWithGraphPath
不返回IAsyncResult
所以我不能使用AsyncWaitHandle
。
编辑
调用代码时:
User u = new User(user);
Console.WriteLine("hello");
我的应用程序输出:
hello
this is a test
这就是让我相信StartWithGraphPath
被称为异步的原因。 还有其他解释吗?
奇怪的是,还有一个名为StartWithGraphPathAsync的方法,那么这个Im是否会通过演绎来同步? 在调试器中具有同步感,但在简单运行应用程序时则不具有同步感
我不会等到它在构造函数中完成。 使异步代码对使用方代码可见(以更友好的形式),并且它可以选择何时或是否实际执行电子邮件值的等待:
public class User
{
public string id, name, image;
public User (IFBGraphUser user)
{
id = user.GetId ();
name = user.GetName ();
GetEmail ();
}
public Task<string> Email {
get{
return emailTask.Task;
}
}
private TaskCompletionSource<string> emailTask =
new TaskCompletionSource<string>();
private void GetEmail()
{
FBRequestConnection.StartWithGraphPath ("/me", null, "GET", ConnectionReturn);
}
private void ConnectionReturn(FBRequestConnection connection, NSObject result, NSError error)
{
var me = (FBGraphObject)result;
Console.WriteLine("this is a test");
emailTask.SetResult(me["email"].ToString());
}
}
一个快速的解决方案是使用ManualResetEvent
或ManualResetEventSlim
,在构造函数中等待它,然后在回调方法中进行设置:
private readonly ManualResetEventSlim myEvent;
public User(IFBGraphUser user)
{
myEvent = new ManualResetEventSlim();
id = user.GetId();
name = user.GetName();
GetEmail();
myEvent.Wait();
}
private void ConnectionReturn(FBRequestConnection connection, NSObject result, NSError error)
{
var me = (FBGraphObject)result;
Console.WriteLine("this is a test");
this.email = me["email"].ToString();
myEvent.Set();
}
请注意 ,仅当StartWithGraphPath方法未使用用于调用该方法调用回调的线程时,此解决方案才有效。 如果确实如此(例如,靠近用户界面的类通常会在UI线程上执行回调),则将发生死锁。 (感谢@LB指出这一点)
如果可以修改类设计,建议从构造函数中删除昂贵的调用。 构造对象通常应该很便宜,并且在其中使用异步方法表明可能会花费一些时间。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.