GZipStream 在 CopyToAsync 的目的地时不调用底层流 *Async 方法
GZipStream does not call underlying streams *Async methods when destination of CopyToAsync
对 GZipStream 使用以下构造,当 GZipStream
是 CopyToAsync
的目标时,它似乎永远不会调用我的自定义流的 *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
方法?
您可以找到此 here
的工作样本
更新:调用初始 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)
您的自定义流实施 BeginWrite
/EndWrite
(以及 BeginRead
/EndRead
)会更正确。如果你用我的 AsyncEx.Tasks
library:
就不难了
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.Tasks
的 1.2.0-alpha-01
版本中)。
对 GZipStream 使用以下构造,当 GZipStream
是 CopyToAsync
的目标时,它似乎永远不会调用我的自定义流的 *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
方法?
您可以找到此 here
的工作样本更新:调用初始 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)
您的自定义流实施 BeginWrite
/EndWrite
(以及 BeginRead
/EndRead
)会更正确。如果你用我的 AsyncEx.Tasks
library:
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.Tasks
的 1.2.0-alpha-01
版本中)。