gpt4 book ai didi

c# - 在 WCF 中使用任务构建异步操作契约(Contract)的正确方法

转载 作者:太空宇宙 更新时间:2023-11-03 15:05:04 25 4
gpt4 key购买 nike

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

[OperationContract(IsOneWay = true)]
[WebInvoke(Method = "POST", UriTemplate = "UploadData", BodyStyle = WebMessageBodyStyle.Bare)]
void UploadData(Stream stream);

由于UploadData会被一个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
}
}
}

当然我可以在 Task 启动之前进行流复制,但这看起来不干净,实际上并不能解决我的困惑。

我的第二个问题是,如果我在操作合约中使用 Task,我应该保持操作合约的签名同步还是异步?如果我将操作契约(Contract)更改为:

[OperationContract(IsOneWay = true)]
[WebInvoke(Method = "POST", UriTemplate = "UploadData", BodyStyle = WebMessageBodyStyle.Bare)]
Task UploadDataAsync(Stream stream);

最佳答案

首先:您不需要Stream incomingStream = stream;

我有一个相同的服务,起初我像你一样实现它。我向您保证,在复制或完成任何类型的过程之前,WCF 不会处理流。但还有另一个问题。您可能会遇到线程外异常。(您可以阅读有关 Task.Run here 的更多信息。)。所以我让我的服务同步,但我称之为异步。这样我就可以达到最大的性能。

关于c# - 在 WCF 中使用任务构建异步操作契约(Contract)的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44014824/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com