等待异步 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
}
所以我对 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
}