WCF Web服务和TPL Task.Run

问题描述

假设我有一个不需要响应的方法,例如:

[ServiceContract]
public interface IWCFTestService
{
    [OperationContract]
    void ReceiveSomeData(MyDto someDtoObj);

}

现在,在实际的服务实现中,我可以编写:

public void ReceiveSomeData(MyDto receivedRequest)
{
    Task.Run( () => OtherProjectOtherClass.DoWhateverYouWant(receivedRequest) )
    
    //... because I am outta here as fast as possible
}

我认为呼叫者将始终获得200-OK;还要注意,我还没有在WCF方法本身内部编写任何异步/等待任务。

以这种方式在WCF内使用TPL是可以接受的吗?

注意:我不关心业务规则,我更关心WCF / TPL以这种方式进行交互在技术上是否可以接受,我会遇到(技术上的)麻烦吗?

解决方法

您需要考虑几件事。

  1. 当任务实际完成时,调用者将不会得到通知,如果完成,则是否失败(例如未处理的异常)也不会得到通知。
  2. 当托管服务的进程停止时,您的任务可能尚未完成,除非您保留对它们的引用,否则您将无法等待它们完成。
  3. 如果OtherProjectOtherClass.DoWhateverYouWant(receivedRequest)中发生未处理的异常,则不会发出信号。因此,请确保将整个身体包含在try..catch中,并进行一些记录或采取其他措施。
  4. 如果发出大量请求,并且任务需要很长时间才能完成,则可能会耗尽线程池中的线程。如果是这样,请使用专用线程,因为Task.Run从池中获取一个线程。

我确实想知道OtherProjectOtherClass.DoWhateverYouWant(receivedRequest)内部发生了什么?是CPU密集型还是更多与I / O相关的?如果它是I / O密集型的,请将其重写为基于任务的方法,而不要使用Task.Run

我无法确定这些问题对您来说真的不是问题,但请记住。