使用PCL中的PUT请求上传带有进度的文件

时间:2015-10-16 05:43:51

标签: c# upload put portable-class-library dotnet-httpclient

如何在.NET PCL中实现put请求?如何禁用写入流缓冲? 我试图在PCL中实现put文件逻辑,但似乎无法找到正确的方法。底层的trasport级别缓冲了流,并且在获得响应期间我的进度被卡住了。因此,它会在复制到内部缓冲区时快速报告,然后在放置请求期间卡住。 AllowWriteStreamBuffering在PCL中不可用,因此我无法从HttpWebRequest获得进展。至于现在我使用以下方法,它也不能正常工作:

using (HttpClient client = new HttpClient())
{   
    client.DefaultRequestHeaders.TransferEncodingChunked = true;            
    ChunkedContent chunkedContent = new ChunkedContent(content, cancellationToken, true, progressInBytes);
    var response = await client.PutAsync(uri, chunkedContent, cancellationToken);
    return await response.Content.ReadAsStreamAsync();
}


public class ChunkedContent : HttpContent
{
    public ChunkedContent(Stream inputStream,CancellationToken token, bool canReportProgress, Action<double> notifyProgressInBytes = null)
    {
        _canReportProgress = canReportProgress;
        _inputStream = inputStream;
        _token = token;
        _notifyProgressInBytes = notifyProgressInBytes;
    }
    private Action<double> _notifyProgressInBytes;
    private bool _canReportProgress;
    private CancellationToken _token;
    const int BufferSize = 4096;        
    private Stream _inputStream;
    protected override async Task SerializeToStreamAsync(System.IO.Stream stream, System.Net.TransportContext context)
    {

        var totalRead = 0L;
        var buffer = new byte[BufferSize];
        var isMoreToRead = true;

        do
        {
            _token.ThrowIfCancellationRequested();

            var read = await _inputStream.ReadAsync(buffer, 0, buffer.Length, _token);

            if (read == 0)
            {
                isMoreToRead = false;
            }
            else
            {
                var data = new byte[read];
                await stream.WriteAsync(buffer, 0, read);                   

                totalRead += read;

                if (_canReportProgress && _notifyProgressInBytes != null)
                {
                    _notifyProgressInBytes(totalRead);
                    System.Diagnostics.Debug.WriteLine(totalRead);
                }
            }
        } while (isMoreToRead);

    }
    protected override bool TryComputeLength(out long length)
    {
        length = _inputStream.Length;
        return true;
    }
}

0 个答案:

没有答案