"Cannot close stream until all bytes are written" WriteAsync 操作取消时

"Cannot close stream until all bytes are written" when WriteAsync operation is Cancelled

当取消对 HttpWebRequest.GetRequestStream() 创建的流的 WriteAsync 操作时,我收到一个 WebException,其中包含以下消息:

Cannot close stream until all bytes are written

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

这是我的工作代码的一部分(我为此 post 清理了一些 headers 所以请求可能格式不正确):

    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();
        }

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