异步WCF服务调用阻止UI线程 [英] Async WCF service call blocking UI thread
问题描述
我们在使用WPF应用程序进行后台调用时遇到了麻烦.看来,在较旧的计算机上(我们最常在具有2GB RAM的Windows 7计算机上看到它),我们的Web服务调用阻止UI 直到完成.特别是对于一个呼叫,这是一个巨大的问题,因为它可能需要五分钟才能完成.较新的计算机似乎可以很好地处理它.
We are having trouble with a background call from our WPF application. Seemingly, on older computers (we have seen it most often on Windows 7 machines with 2GB of RAM or so) our web service call blocks the UI until it completes. For one call in particular, that is a huge problem because it can take five minutes to complete. Newer computers seem to handle it fine.
我们不在乎通话所花费的时间;我们只关心它不会阻塞UI.我看不到我们在做任何错误的事情.
We don't care about the amount of time the call takes; we only care about it not blocking the UI. I do not see anything we are doing wrong off-hand.
我们是在做错什么,还是Windows 7在2GB RAM上发生了什么?在这样的机器上,有什么方法可以解决吗?
Are we doing something wrong, or is it something with Windows 7 on 2GB of RAM? Is theere any way to work around it on such a machine?
我们是否必须达到编写自定义 TaskScheduler
的级别,以确保不使用UI线程?我当然希望不会.
Do we have to go to the level of writing a custom TaskScheduler
to make sure the UI thread does not get used? I sure hope not.
非常感谢任何输入.提前致谢.请参见下面的代码示例.
Any input at all is greatly appreciated. Thanks in advance. See code samples below.
DownloadBusinessEntityAsync
是我们的应用程序调用的方法:
DownloadBusinessEntityAsync
is the method our application calls:
#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客户端实现的合同.
IDownloadService
is the contract the WCF client implements.
[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);
}
推荐答案
如果您只是不想阻止UI,则将其移至后台线程.不需要所有WCF异步内容即可实现您的目标.像这样:
If you simply don't want to block the UI then move that work to a background thread. All that async WCF stuff is not needed to achieve your goal. Something like:
await Task.Run(() => DownloadBusinessEntityAsync(...));
如果愿意,您可以同步 DownloadBusinessEntityAsync
.
And you can make DownloadBusinessEntityAsync
sync if you like.
这篇关于异步WCF服务调用阻止UI线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!