c# - 取消 WriteAsync 操作时为 "Cannot close stream until all bytes are written"

标签 c# asynchronous stream async-await httprequest

HttpWebRequest.GetRequestStream() 创建的流上取消 WriteAsync 操作时,我收到一个 WebException 并显示以下消息:

Cannot close stream until all bytes are written

当我使用 CancellationToken 取消操作时,如何清理我的 HttpWebRequest 和流?

这是我工作代码的一部分(我为这篇文章清理了一些标题,因此请求可能格式不正确):

    public async Task<bool> UploadAsync(FileInfo fi, CancellationToken ct, IProgress<int> progress = null)
    {
        FileStream fs = new FileStream(fi.FullName, FileMode.Open);
        int bufferSize = 1 * 1024 * 1024;
        byte[] buffer = new byte[bufferSize];
        int len;
        long position = fs.Position;
        long totalWrittenBytes = 0;
        HttpWebRequest uploadRequest = null;
        Stream putStream = null;
        try
        {
            while ((len = fs.Read(buffer, 0, buffer.Length)) > 0)
            {

                uploadRequest = (HttpWebRequest)WebRequest.Create("http://myuploadUrl");
                uploadRequest.Method = "PUT";
                uploadRequest.AddRange(position, position + len - 1);
                uploadRequest.ContentLength = len;
                putStream = uploadRequest.GetRequestStream();

                int posi = 0;
                int bytesLeft = len;
                int chunkSize;
                while (bytesLeft > 0)
                {
                    chunkSize = Math.Min(25 * 1024, bytesLeft); //25KB
       //HERE IS the WriteAsync part that is being cancelled           
                    await putStream.WriteAsync(buffer, posi, chunkSize, ct);
                    bytesLeft -= chunkSize;
                    posi += chunkSize;
                    totalWrittenBytes += chunkSize;
                    if (progress != null)
                        progress.Report((int)(totalWrittenBytes * 100 / fs.Length));
                }

                putStream.Close();
                putStream = null;
                position = fs.Position;
                var putResponse = (HttpWebResponse)uploadRequest.GetResponse();
                putResponse.Close();
                uploadRequest = null;
            }

            //putStream.Write(buffer, 0, len);

        }
        catch (OperationCanceledException ex)
        { 
            if (putStream != null)
            {
                putStream.Flush();
                putStream.Close();//WebException occur here: Cannot close stream until all bytes are written.
            }    
        return false;
        }
        finally{
            fs.Close();
        }
        return true;
    }

最佳答案

我终于捕获了 WebException 因为 post 请求必须写入预期的字节数(ContentLength 属性)

这是我最后的收获

        catch (OperationCanceledException ex)
        {
            try
            {
                if (putStream != null)
                    putStream.Dispose();
            }
            catch (WebException) { }
            return false;
        }
        finally{
            fs.Close();
        }

也许我不确定是否应该尝试处理流?

关于c# - 取消 WriteAsync 操作时为 "Cannot close stream until all bytes are written",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28838057/

相关文章:

javascript - 为什么异步函数优于同步函数?

c# - 读取 NetworkStream 不会推进流

c# - TCP 客户端连接

linux - 使用内核 AIO 的应用程序

C# .NET Core 3.1 无法建立 SSL 连接

c# - 将 kinect 骨架位置数据传递到另一个窗口

打开使用 System.IO.Compression 创建的 ZipArchive 时出现 C# .NET 缺少方法异常

ruby - EventMachine、Redis 和 EM HTTP 请求

python - 如何在 python apache beam 中展平多个 Pcollection

c# - 如何通过 Func<TSource,TResult> 列表枚举来过滤集合