C# 使用WCF中的任务构建异步操作契约的正确方法
我正在构建一个WCF服务,它接受来自HTTP客户端的大块数据(通常为4MB)POST,操作契约是一个具有流类型参数的函数,如下所示:C# 使用WCF中的任务构建异步操作契约的正确方法,c#,.net,multithreading,wcf,asynchronous,C#,.net,Multithreading,Wcf,Asynchronous,我正在构建一个WCF服务,它接受来自HTTP客户端的大块数据(通常为4MB)POST,操作契约是一个具有流类型参数的函数,如下所示: [OperationContract(IsOneWay = true)] [WebInvoke(Method = "POST", UriTemplate = "UploadData", BodyStyle = WebMessageBodyStyle.Bare)] void UploadData(Stream stream); 由于上载数据将由I/O完成线程运行,
[OperationContract(IsOneWay = true)]
[WebInvoke(Method = "POST", UriTemplate = "UploadData", BodyStyle = WebMessageBodyStyle.Bare)]
void UploadData(Stream stream);
由于上载数据将由I/O完成线程运行,并且我知道处理数据可能需要一段时间,因此通常我应该尽快将其返回I/O完成线程池,否则并发性将受到影响,因此我计划启动一项任务,将流复制到MemoryStream,并从那里执行以下数据处理。
让我感到困惑的是,由于WCF创建并维护流对象,在Task.Run返回、UploadData退出后,WCF认为此请求已得到服务,但实际上我刚刚开始将流复制到MemoryStream中,如何确保流对象仍处于活动状态,并且在复制完成之前未被WCF处理
public void UploadData(Stream stream)
{
Stream incomingStream = stream; // is variable capture necessary here?
Task.Run(() =>
{
using (MemoryStream memoryStream = new MemoryStream())
{
using (incomingStream)
{
stream.CopyTo(memoryStream);
}
memoryStream.Seek(0, SeekOrigin.Begin);
// process data
}
}
}
当然,我可以在任务开始之前进行流复制,但这看起来并不干净,实际上也不能解决我的困惑
我的第二个问题是,如果我在操作契约中使用任务,我应该保持操作契约的签名同步还是异步?如果我将运营合同更改为:
[OperationContract(IsOneWay = true)]
[WebInvoke(Method = "POST", UriTemplate = "UploadData", BodyStyle = WebMessageBodyStyle.Bare)]
Task UploadDataAsync(Stream stream);
首先:您不需要
streamincomingstream=Stream代码>
我有一个相同的服务,一开始我和你一样实现了它。我向您保证,在复制或执行任何类型的过程之前,WCF不会处理流。但还有另一个问题。您可能会遇到线程外异常。(您可以阅读有关任务的更多信息。运行)。所以我让我的服务同步,但我称之为异步。这样我就可以实现最大的性能