我们在使用WPF应用程序进行后台调用时遇到问题。看起来,在较旧的计算机上(我们最常见的是在具有2GB RAM的Windows 7计算机上)我们的Web服务调用阻止UI 直到它完成。特别是对于一个电话,这是一个很大的问题,因为它可能需要五分钟才能完成。较新的计算机似乎处理得很好。
我们不关心通话所需的时间;我们只关心它没有阻止UI。我手边没有看到任何错误。
我们做错了什么,或者是2GB RAM上的Windows 7?是不是可以在这样的机器上解决它?
我们是否必须达到编写自定义TaskScheduler
的水平以确保UI线程不被使用?我当然希望不会。
非常感谢任何输入。提前致谢。请参阅下面的代码示例。
DownloadBusinessEntityAsync
是我们的应用程序调用的方法:
#region DownloadBusinessEntity
public async Task<BusinessEntity> DownloadBusinessEntityAsync(string businessEnityId)
{
BusinessEntity ret = new BusinessEntity();
var client = new DownloadContext();
try
{
Func<AsyncCallback, object, IAsyncResult> begin = (callback, state) => client.BeginDownloadBusinessEntity(businessEnityId, callback, state);
Func<IAsyncResult, BusinessEntity> end = client.EndDownloadBusinessEntity;
// ***THIS TAKES FIVE MINUTES TO FINISH***
ret = await Task<BusinessEntity>.Factory.FromAsync(begin, end, null);
if (client.State != CommunicationState.Faulted)
client.Close();
else
client.Abort();
}
catch (Exception ex)
{
client.Abort();
}
return ret;
}
#endregion
DownloadContext
是WCF客户端:
public partial class DownloadContext : ClientBase<IDownloadService>, IDownloadService, IDownloadContext, IDisposable
{
public BusinessEntity DownloadBusinessEntity(string agencyId, IEnumerable<int> activeHashCodes)
{
return base.Channel.DownloadBusinessEntity(agencyId, activeHashCodes);
}
public IAsyncResult BeginDownloadBusinessEntity(string agencyId, IEnumerable<int> activeHashCodes, AsyncCallback callback, object asyncState)
{
return base.Channel.BeginDownloadBusinessEntity(agencyId, activeHashCodes, callback, asyncState);
}
public BusinessEntity EndDownloadBusinessEntity(IAsyncResult result)
{
return base.Channel.EndDownloadBusinessEntity(result);
}
}
IDownloadService
是WCF客户端实现的合同。
[ServiceContract(Namespace = "http://namespace.com/services/v1")]
public partial interface IDownloadService
{
[OperationContract(ProtectionLevel=ProtectionLevel.Sign, Action="http://namespace.com/services/v1/IDownloadService/DownloadBusinessEntity", ReplyAction="http://namespace.com/services/v1/IDownloadService/DownloadBusinessEntityResponse")]
BusinessEntity DownloadBusinessEntity(string agencyId, IEnumerable<int> activeHashCodes);
[OperationContract(AsyncPattern=true, ProtectionLevel=ProtectionLevel.Sign, Action="http://namespace.com/services/v1/IDownloadService/DownloadBusinessEntity", ReplyAction="http://namespace.com/services/v1/IDownloadService/DownloadBusinessEntityResponse")]
IAsyncResult BeginDownloadBusinessEntity(string agencyId, IEnumerable<int> activeHashCodes, AsyncCallback callback, object asyncState);
BusinessEntity EndDownloadBusinessEntity(IAsyncResult result);
}
答案 0 :(得分:2)
Microsoft在客户端HTTP连接(HttpWebRequest
和朋友)的实现中存在一个已知问题:它们可以同步工作,包括DNS解析和(我相信)代理检测。即使对于异步请求,此工作也始终同步完成,并且可能需要一些时间,具体取决于您的网络配置。
我不确定WCF客户端是否共享此错误,但这很可能。最佳解决方法是根据usr's answer将其打包在Task.Run
。
答案 1 :(得分:1)
如果您只是不想阻止UI,那么将该工作移至后台线程。所有异步WCF内容都不是实现目标所必需的。类似的东西:
await Task.Run(() => DownloadBusinessEntityAsync(...));
如果您愿意,可以DownloadBusinessEntityAsync
同步。