ASP.NET Web 表单 - 如何异步调用 WCF 异步方法?

Posted

技术标签:

【中文标题】ASP.NET Web 表单 - 如何异步调用 WCF 异步方法?【英文标题】:ASP.NET web forms - how to asynchronously call WCF asynchronous method? 【发布时间】:2017-11-23 13:10:58 【问题描述】:

我创建了一个 WCF 服务并将其托管在 IIS 中。我可以通过在我的 asp.net Web 表单应用程序中创建 Web 引用来访问 WCF 服务。我需要让 WCF Web 服务运行一个长时间运行的方法(异步)。有没有人有很好的示例代码来说明如何从 asp.net Web 表单应用程序按钮单击方法调用 WCF 异步方法?

我查看了 IAsyncResult、EAP 和 TAP... 目前从 ASP.NET Web 表单应用程序对 WCF 异步方法进行异步调用的最佳方式是什么?

我现在确实更改了我的代码以使用服务引用而不是 Web 引用。

Service ReceiptFooterService(ServiceContract、OperationsContract、DataContract):

using System.Collections.Generic;
using System.Net.NetworkInformation;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Threading.Tasks;

namespace ReceiptFooterDeploymentService

    [ServiceContract]
    public interface IReceiptFooterService
    
        [OperationContract(Name = "GetRegisterPingResults")]
        Task<List<PingReply>> GetRegisterPingResults(List<StoreIP> potentialIPs);
    

    [DataContract]
    public class StoreIP
    
        private int _storeNumber;
        private string _ipAddress;

        [DataMember]
        public int StoreNumber
        
            get
            
                return _storeNumber;
            
            set
            
                _storeNumber = value;
            
        

        [DataMember]
        public string IPAddress
        
            get
            
                return _ipAddress;
            
            set
            
                _ipAddress = value;
            
        
    

ReceiptFooterService 类:

using System.Collections.Generic;
using System.Linq;
using System.Net.NetworkInformation;
using System.Threading.Tasks;

namespace ReceiptFooterDeploymentService

    public class ReceiptFooterService : IReceiptFooterService
    
        public async Task<List<PingReply>> GetRegisterPingResults(List<StoreIP> potentialIPs)
        
            var tasks = potentialIPs.Select(sip => new Ping().SendPingAsync(sip.IPAddress, 1000));
            var results = await Task.WhenAll(tasks);

            return results.ToList();
        
    

ASP.NET Web 表单客户端:只有方法的前几行(为简洁起见)

private List<StoreDetail> PingStoreAndUpdateStatus(List<StoreDetail> storeDetails)

    ReceiptFooterService.StoreIP[] potentialIPs = GetStoreRegisterIps(storeDetails).ToArray();
    ReceiptFooterService.ReceiptFooterServiceClient client = new ReceiptFooterService.ReceiptFooterServiceClient();
    List<PingReply> pingReplies = client.GetRegisterPingResultsAsync(potentialIPs).Result.ToList();

我正在尝试异步 ping 大约 2000 个 IP 地址。我得到了四个显示成功的结果。虽然,没有显示其他 PingReply 详细信息。我需要知道被 ping 的 IP 地址。

我是否应该在某个地方等待...这是为什么它很快就会返回,还是有错误导致它失败。任何建议将不胜感激。

下面是我的结果的快速观看:

【问题讨论】:

I need to have the WCF web service run a long running method (async). - async does not yield control to the browser,如果你是这样想的话。 如何让浏览器在完成异步 ping 运行后回调该服务? 我推荐使用 SignalR。 【参考方案1】:

首先,在使用 WCF 时为什么不使用服务引用? (Web vs Service reference) 然后,当使用 SOAP 客户端时,它会自动生成带有同步和asynchronous 变体的每个方法的 SOAP WCF 客户端。 然后你就调用这个异步方法

MyServiceClient.DummyMethodAsync(someParameters...)

【讨论】:

如果我显示我的源代码可能会有所帮助。我稍后会发布。【参考方案2】:

我发现使用 WCF Web 服务来完成我需要做的那种异步工作(不是在 Web 服务中工作)。

我转而创建一个使用参数调用的控制台应用程序,然后将结果存储在数据库中。然后我让网站访问存储在数据库中的结果。

控制台应用程序上下文对于完成我想同时运行的大量异步方法更加友好。

【讨论】:

以上是关于ASP.NET Web 表单 - 如何异步调用 WCF 异步方法?的主要内容,如果未能解决你的问题,请参考以下文章

异步 asp.net 表

Asp.Net - 从不同的应用程序层异步调用 web 服务,而不是页面本身

$Ajax ASP.NET Web 方法调用中的错误 [异步]

使用ajax调用asp.net web表单代码

asp.net ajax客户端框架如何调用Web Service

在asp.net里怎样异步调用WebService方法