【问题标题】:"Cannot close stream until all bytes are written" when WriteAsync operation is Cancelled取消 WriteAsync 操作时,“在写入所有字节之前无法关闭流”
【发布时间】:2015-05-04 11:21:39
【问题描述】:

当取消WriteAsyncHttpWebRequest.GetRequestStream() 创建的流的操作时,我收到带有以下消息的 WebException:

在写入所有字节之前无法关闭流

当我使用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;
    }

【问题讨论】:

    标签: c# asynchronous stream async-await httprequest


    【解决方案1】:

    我终于抓住了WebException,因为发布请求必须写入预期的字节数(ContentLength 属性)

    这是我最后的收获

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-23
      • 1970-01-01
      • 2013-10-11
      • 2013-09-25
      相关资源
      最近更新 更多