gpt4 book ai didi

c# - gRPC C# : how to cancel upload correctly

转载 作者:行者123 更新时间:2023-12-05 07:15:52 25 4
gpt4 key购买 nike

为了将图像从客户端上传到服务器,我使用分块。

这是客户端代码:

private async Task UploadPersonImage(int personId, string fileName, CancellationToken cancellationToken)
{
var stream = Client.UploadPersonImage();
PersonImageMessage personImageMessage = new PersonImageMessage();
personImageMessage.PersonId = personId;
personImageMessage.ImageType = ImageType.Jpg;
byte[] image = File.ReadAllBytes(fileName);
int imageOffset = 0;
byte[] imageChunk = new byte[imageChunkSize];
while (imageOffset < image.Length && !cancellationToken.IsCancellationRequested)
{
int length = Math.Min(imageChunkSize, image.Length - imageOffset);
Buffer.BlockCopy(image, imageOffset, imageChunk, 0, length);
imageOffset += length;
ByteString byteString = ByteString.CopyFrom(imageChunk);
personImageMessage.ImageChunk = byteString;
await stream.RequestStream.WriteAsync(personImageMessage).ConfigureAwait(false);
}
await stream.RequestStream.CompleteAsync().ConfigureAwait(false);
if (!cancellationToken.IsCancellationRequested)
{
var uploadPersonImageResult = await stream.ResponseAsync.ConfigureAwait(false);
// Process answer...
}
}

这是服务器代码:

public override async Task<TransferStatusMessage> UploadPersonImage(
IAsyncStreamReader<PersonImageMessage> requestStream, ServerCallContext context)
{
TransferStatusMessage transferStatusMessage = new TransferStatusMessage();
transferStatusMessage.Status = TransferStatus.Success;
try
{
await Task.Run(
async () =>
{
CancellationToken cancellationToken = context.CancellationToken;
await using (Stream fs = File.OpenWrite(ImageFileName))
{
await foreach (PersonImageMessage personImageMessage in
requestStream.ReadAllAsync(cancellationToken).ConfigureAwait(false))
{
fs.Write(personImageMessage.ImageChunk.ToByteArray());
}
}
}).ConfigureAwait(false);
}
// Is thrown on cancellation -> ignore...
catch (OperationCanceledException)
{
transferStatusMessage.Status = TransferStatus.Cancelled;
}
catch (RpcException rpcEx)
{
if (rpcEx.StatusCode == StatusCode.Cancelled)
{
transferStatusMessage.Status = TransferStatus.Cancelled;
}
else
{
_logger.LogError($"Exception while processing image file '{ImageFileName}'. Exception: '{requestStream}'");
transferStatusMessage.Status = TransferStatus.Failure;
}
}
// Delete incomplete file
if (transferStatusMessage.Status != TransferStatus.Success)
{
File.Delete(ImageFileName);
}
return transferStatusMessage;
}

一切正常。我想在发送 block 之间取消上传。现在,CompleteAsync() 被调用,服务器认为数据传输成功结束。我正在寻找一种方法来通过客户端触发服务器中的取消(即 ServerCallContext 中的 CancellationToken)。作为解决方法,我可以向 PersonImageMes​​sage 添加一个标志,例如“upload_cancelled”,以告知服务器传输已中止。但必须有一个内置的机制。

有人知道这个技巧吗?

最佳答案

您可以将 cancellationToken 传递给您的客户端流 RPC 方法。然后服务器可以将其作为 context.cancellationToken 接收。

var stream = Client.UploadPersonImage(cancellationToken: cancellationToken);

如果客户端取消,则不应调用 stream.RequestStream.CompleteAsync()

关于c# - gRPC C# : how to cancel upload correctly,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59452284/

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