【问题标题】:WCF Web Service and TPL Task.RunWCF Web 服务和 TPL Task.Run
【发布时间】:2020-10-05 01:56:25
【问题描述】:

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

[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 方法本身内编写任何任务 async/await。

以这种方式在 WCF 中使用 TPL 是否可以接受,有什么问题吗?

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

【问题讨论】:

    标签: wcf task-parallel-library


    【解决方案1】:

    您必须考虑几件事情。

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

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

    我无法判断这些问题对您来说是否真的是问题,但请记住这一点。

    【讨论】:

    • 实际上,DoWhateverYouWant() 内部发生的“没什么”。只需登录到数据库,向调用者(在其端的服务)发出确认,然后再处理请求。不过谢谢指点。
    • 我没有想到 #2,如果托管服务的进程停止,(子)任务也会停止 - 但这与我没有任务没有什么不同,而且所有代码在 WCF 方法中,它也会停止。
    • 正常,当服务主机正常结束时,调用 close 方法并等待挂起的请求,这样的任务不会发生这种情况。
    猜你喜欢
    • 2014-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多