加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 在[IsOneWay = true] WCF服务异步和使用客户端上的任务调

发布时间:2020-12-16 00:08:20 所属栏目:百科 来源:网络整理
导读:如果我有一个定义的服务: [ServiceContract(SessionMode = SessionMode.NotAllowed)]public interface IMyService{ [OperationContract(IsOneWay = true)] [ReceiveContextEnabled(ManualControl = true)] void DoSomething(MessageXElement message);} 我
如果我有一个定义的服务:

[ServiceContract(SessionMode = SessionMode.NotAllowed)]
public interface IMyService
{
    [OperationContract(IsOneWay = true)]
    [ReceiveContextEnabled(ManualControl = true)]
    void DoSomething(Message<XElement> message);
}

我想从我的客户端异步调用它(使用不从svcutil生成的共享契约或添加服务引用)我可以这样做:

Task task = Task.Factory.StartNew(() => myService.DoSomething(message));

... some other code

task.Wait();

我还可以将我的服务定义为异步:

[ServiceContract(SessionMode = SessionMode.NotAllowed)]
public interface ICacheKeyExchangeAsync
{
    [OperationContract(IsOneWay = true,AsyncPattern = true)]
    [ReceiveContextEnabled(ManualControl = true)]
    IAsyncResult BeginDoSomething(Message<XElement> message,AsyncCallback callback,object state);
    void EndDoSomething(IAsyncResult result);
}

而是这样做

IAsyncResult result = myService.BeginDoSomething(message,null,null);

.... some other code

myService.EndDoSomething(result);

这些方法之间是否存在显着差异?

解决方法

是的,Thread Pool线程利用率存在差异.

CLR线程池分为两种类型的线程:worker和I / O(有关它们的更多信息,可以在Simple description of worker and I/O threads in .NET和MSDN找到).一般来说,线程池为每个核心提供250个工作线程和1000个I / O线程,因此您可以使用工作线程处理您的WCF服务输入,并使用I / O线程等待异步发送/接收操作完成(这是支持的)在Windows操作系统级别上overlapped I/O机制).

记住这一点,让我们看一下使用ThreadPool.GetAvailableThreads()方法将两种方法用于哪些线程:

int worker;
 int ioCompletion;
 ThreadPool.GetAvailableThreads(out worker,out ioCompletion);
 Console.WriteLine("{0} worker and {1} I/O threads are available",worker,ioCompletion);

我将仅显示客户端的线程池利用率的结果,但对于服务器端也是如此.

用于单向WCF操作的APM方法.

对于WCF合同:

[ServiceContract]
 public interface IService1
 {
     [OperationContract(IsOneWay = true,AsyncPattern = true)]
     IAsyncResult BeginDoSomething(int value,object state);

     void EndDoSomething(IAsyncResult result);
 }

让我们使用下一个代码从客户端向服务器发送100个请求:

ChannelFactory<IService1> channelFactory = new ChannelFactory<IService1>();
var client = channelFactory.CreateChannel();

for (int i = 0; i < 100; i++)
{
    int worker;
    int ioCompletion;
    ThreadPool.GetAvailableThreads(out worker,out ioCompletion);
    Console.WriteLine("{0} worker and {1} I/O threads are available",ioCompletion);

    client.BeginDoSomething(i,asyncCallback,null);
}

输出是:

1023 worker and 1000 I/O threads are available
1023 worker and 998 I/O threads are available
1023 worker and 996 I/O threads are available
1023 worker and 996 I/O threads are available
1023 worker and 996 I/O threads are available
1023 worker and 998 I/O threads are available
1023 worker and 998 I/O threads are available
1023 worker and 999 I/O threads are available
1023 worker and 998 I/O threads are available
1023 worker and 998 I/O threads are available
1023 worker and 998 I/O threads are available
1023 worker and 999 I/O threads are available
1023 worker and 999 I/O threads are available
1023 worker and 999 I/O threads are available
1023 worker and 998 I/O threads are available
1023 worker and 998 I/O threads are available
1023 worker and 998 I/O threads are available
1023 worker and 999 I/O threads are available

正如您所看到的,我的x4核心机器上可以使用所有工作线程,并且正在使用多个I / O线程.

作为TPL任务运行同步单向操作.

对于WCF合同:

[ServiceContract]
 public interface IService2
 {
     [OperationContract(IsOneWay = true)]
     void DoSomething(int value);
 }

让我们使用下一个代码运行从客户端到服务器的100个请求(只是想注意TPL使用CLR ThreadPool发动机罩):

for (int i = 0; i < 100; i++)
{
    int worker;
    int ioCompletion;
    ThreadPool.GetAvailableThreads(out worker,ioCompletion);

    Task.Run(() => client.DoSomething(i));
}

输出是:

1023 worker and 1000 I/O threads are available
1022 worker and 1000 I/O threads are available
1021 worker and 1000 I/O threads are available
1020 worker and 1000 I/O threads are available
1019 worker and 1000 I/O threads are available
1019 worker and 1000 I/O threads are available
1019 worker and 1000 I/O threads are available
1019 worker and 1000 I/O threads are available
1019 worker and 1000 I/O threads are available
1019 worker and 1000 I/O threads are available
1019 worker and 1000 I/O threads are available
1019 worker and 1000 I/O threads are available
1019 worker and 1000 I/O threads are available
1019 worker and 1000 I/O threads are available
1019 worker and 1000 I/O threads are available
1019 worker and 1000 I/O threads are available
1019 worker and 1000 I/O threads are available
1019 worker and 1000 I/O threads are available
1019 worker and 1000 I/O threads are available
1019 worker and 1000 I/O threads are available

如您所见,现在正在使用工作线程,但不使用I / O线程.

那么,推荐的方法是什么?

总之,您的解决方案应该:

>利用线程池中的工作线程和I / O线程(特别是对于高负载的应用程序)来防止出现瓶颈;
>在Task中包装异步操作,这样您就可以获得TPL和新的C#async / await功能的所有好处;
>异步执行OneWay操作是绝对合理的
(考虑,实际上有时是OneWay is not OneWay).

因此,推荐的方法是Task-based asynchronous pattern for WCF,满足上述所有要求.

WCF的基于任务的异步模式.

合同:

[ServiceContract]
public interface IService3
{
    [OperationContract(IsOneWay = true)]
    Task DoSomethingAsync(int value);
}

让我们再次发送100个请求:

for (int i = 0; i < 100; i++)
{
     int worker;
     int ioCompletion;
     ThreadPool.GetAvailableThreads(out worker,out ioCompletion);
     Console.WriteLine("{0} worker and {1} I/O threads are available",ioCompletion);
     client.DoSomethingAsync(i);
}

输出:

1023 worker and 1000 I/O threads are available
1023 worker and 998 I/O threads are available
1023 worker and 999 I/O threads are available
1023 worker and 998 I/O threads are available
1023 worker and 999 I/O threads are available
1023 worker and 998 I/O threads are available
1023 worker and 998 I/O threads are available
1023 worker and 999 I/O threads are available
1023 worker and 999 I/O threads are available
1023 worker and 998 I/O threads are available
1023 worker and 999 I/O threads are available
1023 worker and 998 I/O threads are available
1023 worker and 999 I/O threads are available

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读