WCF Web 服务和 TPL Task.Run
WCF Web Service and 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 方法本身中编写任何任务 async/await。
以这种方式在 WCF 中使用 TPL 是否可以接受,有什么问题吗?
注意:我不关心业务规则,我更关心WCF/TPL这样的交互在技术上是否可以接受,我运行陷入(技术)麻烦?
您必须考虑几件事。
- 调用者不会在任务实际完成时收到通知,如果完成了,无论是否失败(例如未处理的异常)。
- 当托管服务的进程停止时,您的任务可能尚未完成,除非您保留对它们的引用,否则您将无法等待它们完成。
- 如果
OtherProjectOtherClass.DoWhateverYouWant(receivedRequest)
中发生未处理的异常,您将不会收到信号。因此,请确保整个主体都包含在 try..catch 中并应用一些日志记录或采取其他措施。
- 如果发出大量请求并且任务需要很长时间才能完成,您可以 运行 线程池中的线程不足。如果是这样,请使用专用线程,因为
Task.Run
从池中获取一个线程。
我很想知道,OtherProjectOtherClass.DoWhateverYouWant(receivedRequest)
里面发生了什么?它是 CPU 强化还是更多 I/O 相关?如果它是 I/O 密集型,请将其重写为基于任务的方法,而不是使用 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 方法本身中编写任何任务 async/await。
以这种方式在 WCF 中使用 TPL 是否可以接受,有什么问题吗?
注意:我不关心业务规则,我更关心WCF/TPL这样的交互在技术上是否可以接受,我运行陷入(技术)麻烦?
您必须考虑几件事。
- 调用者不会在任务实际完成时收到通知,如果完成了,无论是否失败(例如未处理的异常)。
- 当托管服务的进程停止时,您的任务可能尚未完成,除非您保留对它们的引用,否则您将无法等待它们完成。
- 如果
OtherProjectOtherClass.DoWhateverYouWant(receivedRequest)
中发生未处理的异常,您将不会收到信号。因此,请确保整个主体都包含在 try..catch 中并应用一些日志记录或采取其他措施。 - 如果发出大量请求并且任务需要很长时间才能完成,您可以 运行 线程池中的线程不足。如果是这样,请使用专用线程,因为
Task.Run
从池中获取一个线程。
我很想知道,OtherProjectOtherClass.DoWhateverYouWant(receivedRequest)
里面发生了什么?它是 CPU 强化还是更多 I/O 相关?如果它是 I/O 密集型,请将其重写为基于任务的方法,而不是使用 Task.Run
.
我不知道这些问题对你来说是否真的是问题,但请记住这一点。