C# 使用WCF中的任务构建异步操作契约的正确方法

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完成线程运行,

我正在构建一个WCF服务,它接受来自HTTP客户端的大块数据(通常为4MB)POST,操作契约是一个具有流类型参数的函数,如下所示:

[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不会处理流。但还有另一个问题。您可能会遇到线程外异常。(您可以阅读有关
任务的更多信息。运行
)。所以我让我的服务同步,但我称之为异步。这样我就可以实现最大的性能