我正在尝试在复制文件时实现进度通知机制。 我是按照以下方式做到的:
请帮忙解决此问题。
更新源代码:
private void StartAsyncCopying()
{
var sourceFileInfo = new FileInfo(Source);
if (!sourceFileInfo.Exists)
{
throw new FileNotFoundException("File not found.",
Source);
}
m_sourceLength = sourceFileInfo.Length;
m_readerStream = new FileStream(Source, FileMode.Open);
m_writerStream = new FileStream(Target, FileMode.Create);
m_queueBuffer = new Queue<byte[]>(DefaultQueueBufferSize);
m_queueBufferLock = new object();
ProgressRead();
}
private void ProgressRead()
{
var readerChunck = new byte[DefaultChunckSize];
var streamChunck = new StreamChunck(readerChunck, m_readerStream);
m_readerStream.BeginRead(streamChunck.Chunck,
0,
streamChunck.Chunck.Length,
ReadCallback,
streamChunck);
}
private void ReadCallback(IAsyncResult asyncResult)
{
var streamChunck = asyncResult.AsyncState as StreamChunck;
var numberOfBytesRead = streamChunck.Stream.EndRead(asyncResult);
m_readerOffset += numberOfBytesRead;
ProgressWrite(streamChunck.Chunck);
}
private void ProgressWrite(byte[] chunck)
{
var streamChunck = new StreamChunck(chunck, m_writerStream);
m_writerAsyncResult = m_writerStream.BeginWrite(streamChunck.Chunck,
0,
streamChunck.Chunck.Length,
WriteCallback,
streamChunck);
}
private void WriteCallback(IAsyncResult asyncResult)
{
var streamChunck = asyncResult.AsyncState as StreamChunck;
var numberOfBytesWritten = streamChunck.Stream.EndRead(asyncResult);
m_writerOffset += numberOfBytesWritten;
var progressChangedEventArgs = new CopyProgressChangedEventArgs(m_operationDescription,
m_sourceLength,
m_writerOffset);
OnCopyProgressChanged(progressChangedEventArgs);
if (m_writerOffset == m_sourceLength)
{
var copyCompletedEventArgs = new CopyCompletedEventArgs(m_operationDescription, null);
OnCopyCompleted(copyCompletedEventArgs);
}
else
{
ProgressRead();
}
}
答案 0 :(得分:4)
当您致电BeginXXX
时,您可能会收到IAsyncResult
个对象,要拨打EndXXX
,您需要将此IAsyncResult
引用传递给该方法。如果您使用了Read中的相同对象并将其传递给Write,则它将无法工作 - 在您的场景中将有两个单独的IAsyncResult
对象。
当我这样做时,我将对返回的IAsyncResult
的引用保留为本地类变量(如果使用回调)。当我致电EndXXX
时,我会提供此本地参考(从我的初始BeginXXX
获得)并在之后将其归零以表示它可以重复使用。
更新2:查看您的代码,EndWrite
中的WriteCallback
实际上是EndRead
,野餐错误: - )
更新1:以下对我来说很好......
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace ConsoleApplication14
{
class Program
{
static FileStream fs = null;
static MemoryStream ms = null;
static byte[] buffer = new byte[512];
static void Main(string[] args)
{
fs = new FileStream("theFile", FileMode.Open);
fs.BeginRead(buffer, 0, 512, new AsyncCallback(ReadFinished), null);
Console.Read();
}
static void ReadFinished(IAsyncResult res)
{
fs.EndRead(res);
fs.Dispose();
ms = new MemoryStream();
ms.BeginWrite(buffer, 0, 512, new AsyncCallback(WriteFinished), null);
}
static void WriteFinished(IAsyncResult res)
{
ms.EndWrite(res);
ms.Dispose();
}
}
}
答案 1 :(得分:2)
你有以下内容:
private void WriteCallback(IAsyncResult asyncResult)
{
var streamChunck = asyncResult.AsyncState as StreamChunck;
var numberOfBytesWritten = streamChunck.Stream.EndRead(asyncResult);
^^^^^^^
但你正在写作。你不应该打电话给EndWrite
吗?或者我错过了一些非常明显的东西?
该方法中也有ProgressRead();
。