当WriteAsync操作被取消时,“在写入所有字节之前无法关闭流”

时间:2015-03-03 17:24:29

标签: c# asynchronous stream async-await httprequest

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

  

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

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

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

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

1 个答案:

答案 0 :(得分:0)

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

这是我的最后一次抓捕

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

也许我不确定我是否应该费心去处理这个流?