gpt4 book ai didi

c# - 单声道中的异步 WCF 调用陷入无限循环

转载 作者:太空宇宙 更新时间:2023-11-03 13:21:00 26 4
gpt4 key购买 nike

我在调用 WCF 服务异步的 MonoAndroid 中遇到问题。我按照本教程创建了可移植类库。 http://nullskull.com/a/10476775/xamarin-cross-platform-application-consuming-wcf--part-1.aspx

这是调用 WCF 服务的服务方法:

public async static Task<KeyExchangeModel> GetPublicKeyFromServer(KeyExchangeModel model)
{
try
{
ISyncService client;
client = new SyncServiceClient(_binding, _endpointAddress);

var res = Task<KeyExchangeModel>.Factory.FromAsync(client.BeginGetServerPublicKey, client.EndGetServerPublicKey,
model, null);
await res;
return res.Result;
}
catch (Exception e)
{
return null;
}
}

我在这里调用方法并等待它执行。

Task<KeyExchangeModel> task = SyncServiceAgent.GetPublicKeyFromServer(keyModel);
task.Wait();
KeyExchangeModel serverModel = task.Result;

问题是在 Android 上我从来没有得到结果。它卡在一个循环中。设备日志中没有记录或抛出任何异常。

此代码完美适用于 Windows 单元测试和 Windows Phone 项目。

我希望有人能帮助我。

非常感谢。

最佳答案

你的问题是这里的这一行:task.Wait();阻塞异步代码会导致死锁。

默认情况下,await将捕获当前“上下文”,并使用该上下文恢复 async方法。在这种情况下,它可能正在捕获与 UI 线程相关联的 UI 上下文。所以,GetPublicKeyFromServer将启动 WCF 调用、捕获 UI 上下文并返回未完成的任务。然后调用代码调用 Task.Wait在该任务上,它阻塞 UI 线程,直到该异步方法完成。

稍后,WCF 调用返回,并且 GetPublicKeyFromServer尝试在相同的上下文中(在 UI 线程上)恢复。但是,UI 线程被阻塞等待 GetPublicKeyFromServer去完成。这是典型的死锁情况。

它在单元测试中起作用的原因是因为 async方法捕获线程池上下文而不是 UI 上下文,因此它能够在 Wait 中阻塞一个线程池线程。而另一个线程池线程可以完成async方法。通常情况下,Windows Phone 应用程序在 UI 上下文方面会遇到与 Android 应用程序相同的问题,因此我怀疑测试代码有一些不同,这就是它不会在 WP 上死锁的原因。

我更详细地描述了这个问题on my blog , in an MSDN article , 和 in my book .

此问题的最佳解决方案是使用 await而不是 Task.WaitTask<T>.Result .即,您的调用代码应该是:

Task<KeyExchangeModel> task = SyncServiceAgent.GetPublicKeyFromServer(keyModel);
KeyExchangeModel serverModel = await task;

这将要求您的调用代码为 async ,这又要求它的调用者是async等。异步在代码库中的这种“增长”是自然而正常的。

关于c# - 单声道中的异步 WCF 调用陷入无限循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24181595/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com