等待异步 Web 服务调用在任务中完成

Wait for Async Web Service Call to finish inside Task

所以我对 Windows 电话和 C# 有点陌生,所以我知道我的设置方式可能有误,所以也许有人可以为我指出正确的方向。在移动应用程序中,我们需要能够调用特定服务以生成会话 guid,然后再继续对其他方法的任何调用,因此从我目前所读的内容来看,我需要将该调用放在任务,然后我可以使用 await 方法来防止调用下一个项目,但我无法弄清楚的是如何在任务内调用 Web 服务方法并在任务完成之前获取结果。到目前为止,这是我所拥有的,我已经从各种来源尝试了一些其他的东西,但没有奏效,所以我决定将它剥离回我的第一次尝试,然后 post 在这里寻求帮助。

public static async Task<Guid> GetAMSessionGUID()
{
    Debug.WriteLine("setting up client");
    AMClient client = new AMClient();
    Guid session = new Guid();
    client.GetSessionCompleted += delegate(object sender, GetSessionCompletedEventArgs e)
    {
        session = e.Result.session_ID;
        Debug.WriteLine("session completed " + session);
    };
    client.GetSessionAsync();
    return session;
}

您应该 await 您调用的异步方法(通常是那些以 Async 结尾的方法)。

所以在你提供的方法中,你应该await client.GetSessionAsync();

然后您应该等待调用您自己的方法(并且惯用地,您也应该在其名称中添加 Async 后缀)。

什么是AMClient类型? GetSessionAsync() 方法是如何声明的?

根据您问题的性质,我猜测该方法是这样声明的:

public void GetSessionAsync()

并且 "async" 指的是方法 returns 立即执行,并在操作实际完成时引发 GetSessionCompleted 事件。如果是这样,那么您可以使用 TaskCompletionSource<T> class 来帮助您为您的方法实现 async/await 友好包装器。例如:

public static Task<Guid> GetAMSessionGUIDAsync()
{
    Debug.WriteLine("setting up client");
    AMClient client = new AMClient();
    TaskCompletionSource<Guid> completionSource = new TaskCompletionSource<Guid>();

    client.GetSessionCompleted += (sender, e) =>
    {
        Debug.WriteLine("session completed " + session);
        completionSource.SetResult(e.Result.session_ID);
    };
    client.GetSessionAsync();

    return completionSource.Task;
}

方法本身不需要 async,因为它实际上并不在等待任何东西。请注意,我还将您的事件订阅更改为更简洁的 lambda 语法,并重命名了该方法,以便名称以单词 Async 结尾,此类方法的 .NET 约定。

TaskCompletionSource<T>对象做了两件相关的事情:它给你一个地方来存储操作的结果;它给你一个 Task<T> 代表操作,并且可以像任何其他 Task<T>.

一样等待

因此,通过上面实现的方法,您可以像这样使用它:

async Task DoSomeStuff()
{
    // do initial stuff

    Guid sessionGuid = await GetAMSessionGUIDAsync();

    // do some other stuff
}