繁体   English   中英

等待异步方法返回

[英]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());
    }

}

一个快速的解决方案是使用ManualResetEventManualResetEventSlim ,在构造函数中等待它,然后在回调方法中进行设置:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM