WCF service asynchronous blocking UI thread

We are having problems with the background call from our WPF application. Apparently, on older computers (we saw this most often on Windows 7 machines with 2 GB of RAM or so), our web service call blocks the user interface until it finishes. For one call, in particular, this is a huge problem because it can take five minutes. Newer computers seem to handle this.

We do not care about how long the call takes; we take care of this without blocking the user interface. I do not see anything that we are doing wrong.

Are we doing something wrong, or is it something with Windows 7 on 2 GB of RAM? Is there any way around it on such a machine?

Do we need to go to the writing level of the user TaskSchedulerto make sure that the user interface stream is not used? I hope no.

Any input is appreciated. Thanks in advance. See Code Examples below.

DownloadBusinessEntityAsync - the method that 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 client:

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 - This is a contract that 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);

}

+1
source share
2 answers

If you just do not want to block the user interface, move this work to a background thread. All that asynchronous WCF is not needed to achieve your goal. Sort of:

await Task.Run(() => DownloadBusinessEntityAsync(...));

And you can do DownloadBusinessEntityAsyncsynchronization if you want.

+1
source

Microsoft HTTP- (HttpWebRequest ): , DNS ( ) . , .

, WCF- , . Task.Run usr.

+2

Source: https://habr.com/ru/post/1666013/


All Articles