GZipStream不调用底层流*Async方法时的目的地CopyToAsync

本文关键字:方法 目的地 CopyToAsync Async 调用 GZipStream | 更新日期: 2023-09-27 18:15:19

使用以下构造的GZipStream,当GZipStreamCopyToAsync的目的地时,它似乎永远不会调用我的自定义流的*Async方法。

using (var fs = new System.IO.FileStream(@"C:'BTR'Source'Assemblies'BTR.Rbl.Evolution.Documents.dll", 
        System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.None, 8192, true))
{
    using (var ss = new GZipStream(new MyCustomStream(), CompressionMode.Compress))
    {
        await fs.CopyToAsync(ss);
    }
}

似乎只调用BeginWrite/EndWrite机制。是否有一种方法可以从GZipStream派生,使其调用WriteAsync,而不是让我的自定义流不必实现WriteAsync方法以及BeginWrite/EndWrite方法?

你可以在这里找到一个工作示例

更新:Callstack当初始Write()方法被调用

SampleStream.Write(buffer, offset, count)
System.IO.Compression.DeflateStream.DoMaintenance(array, offset, count)
System.IO.Compression.DeflateStream.InternalWrite(array, offset, count, isAsync)
System.Runtime.Remoting.Messaging.StackBuilderSink.AsyncProcessMessage(msg, replySink)
System.Runtime.Remoting.Proxies.AgileAsyncWorkerItem.ThreadPoolCallBack(o)
System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(state)
System.Threading.ExecutionContext.RunInternal(executionContext, callback, state, preserveSyncCtx)
System.Threading.ExecutionContext.Run(executionContext, callback, state, preserveSyncCtx)
System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()
(Unmanaged code)

GZipStream不调用底层流*Async方法时的目的地CopyToAsync

您的自定义流实现BeginWrite/EndWrite(以及BeginRead/EndRead)会更正确。这并不难,如果你使用我的AsyncEx.Tasks库:

public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count,
    AsyncCallback callback, object state)
{
  var task = WriteAsync(buffer, offset, count);
  return ApmAsyncFactory.ToBegin(task, callback, state);
}
public override void EndWrite(IAsyncResult asyncResult)
{
  ApmAsyncFactory.ToEnd(asyncResult);
}

(ApmAsyncFactory已添加到AsyncEx.Tasks1.2.0-alpha-01版本)。