C#如何在WCF回调中使用具有APM-TAP模式的完成端口执行Asynchrounus I / O?

时间:2016-01-31 13:14:09

标签: c# multithreading wcf threadpool iocp

我正在尝试在双工合同中使用WCF回调来利用I / O完成端口。我使用以下简单的行来执行此操作:

OperationContext.Current.OnPushData(data);

OnPushData 是在客户端实施的回调合约操作。
由于此行表示使用某个网络接口的响应(输出操作), WCF 也依赖于 ThreadPool 线程,可用作工作线程或I / O CompletionPortThread通过使用 TAP或APM 模式(正如我提到的文章建议的那样)写入完成端口来利用I / O CompletionPortThreads是一个好主意,而不是使用会增加的普通工作线程表现相当可观。

1 个答案:

答案 0 :(得分:0)

简答:
能够与双工WCF合同一起使用异步I / O的技巧是以下简单代码:

    [OperationContract(IsOneWay = true)]
    Task OnPushData(data);

您只需将回调合约方式的退货类型更改为任务。但这还不够,你需要像这样实现异步方法

    public async Task PublishData()
    {
        communicationCallback = (ICommunicationObject)service.Callback;
        if (communicationCallback.State == CommunicationState.Opened)
        {
                await service.Callback.OnPushData(data);
        }
    }

就是这样。 这实际上提升了我的应用程序的性能。现在我能够看到I / O完成端口线程使用调用 ThreadPool.GetAvailableThreads(工作者,IO)

一些说明:
据我了解,为了能够使用异步I / O机制,您需要执行以下操作:

1-确定您的I / O操作 2-一种封装异步I / O逻辑的方法 3-异步I / O完成时将调用的回调机制,其目的主要是获取异步I / O的结果。
4-将保存Async I / O结果的对象。

.NET framework 提供了3种设计模式:

1- IAsyncResult Asynchrnous Pattern 其中 Beginxxx Endxxx 将封装您的异步逻辑以及 Callback Delegate 表示回调方法,当然还有用于保存异步I / O结果的 IAsyncResult 对象。
2- 基于任务的异步模式:仅使用一个任务的类以及便于使用TAP模式的async / await关键字。
3- 基于事件的异步模式。

您可以在How to Implement an Asynchronous Service Operation

了解有关如何在WCF服务中使用这些模式的更多信息

但是,之前的链接非常适合实现异步请求/响应服务,但是没有关于如何使用回调合同的解释。
不幸的是,在我的情况下,我必须使用WCF框架实现订阅者/发布者模式,其中数据发布由服务端定期(每1秒)发起。

更多详情:
我会尽量缩短它:
WCF依赖于.NET Framework提供的ThreadPool。 ThreadPool有两种线程:
1- 工作线程:用于计算绑定操作 2- I / O完成端口线程用于获取I / O操作的结果。

您必须区分CLR启动的IOCP线程和IOCP对象。 IOCP线程角色是提供I / O操作的结果,而IOCP对象是由CLR发起的用于接收所有I / O请求的对象。换句话说,他们合作实现I / O操作。

您需要知道的第一件事是,您所做的任何I / O请求都将导致系统调用,该系统调用将启动一个名为 IRP(I / O请求数据包)的对象,无论您是否使用同步或异步范例。

I / O完成端口( IOCP )只不过是由 CLR 启动的类似队列的对象。此对象负责接收所有 I / O已完成请求 IRP )。此时有两种可能性:
1-您的I / O操作由同步方法调用:在这种情况下,调用程序线程将被阻塞,直到您的I / O操作完成。
2-您的I / O操作由异步方法调用:在这种情况下,调用程序线程将继续执行,并且在完成之前不会阻止I / O操作。

假设您正在使用异步方法,当您的异步I / O操作完成时,这意味着 IRP 对象已处理,现在它将排队到 IOCP 宾语。 ThreadPool IOCP线程将扮演从 IOCP 中拉出相对 IRP 的角色,它将包含在 IAsyncResult 中用于TAP的APM或任务对象,并通过回调机制将此对象传递到您的应用程序级别。

一些参考文献:

  

[1]:https://msdn.microsoft.com/en-us/library/ms734701.aspx
  [2]:http://blog.stephencleary.com/2012/08/async-wcf-today-and-tomorrow.html
  [3]:http://southworks.com/blog/2013/10/29/asynchronous-io-in-c-io-completion-ports/
  [4]:http://southworks.com/blog/2013/08/02/asynchronous-io-in-c-introduction/
  [5]:http://mikehadlow.blogspot.com/2011/03/7000-concurrent-connections-with.html
  [6]:https://msdn.microsoft.com/en-us/library/ms731177(v=vs.110).aspx
  [7]:http://www.amazon.es/Clr-Via-C-Developer-Reference/dp/0735667454