我日复一日熟悉C#,我遇到了这段代码
public static void CopyStreamToStream(
Stream source, Stream destination,
Action<Stream,Stream,Exception> completed) {
byte[] buffer = new byte[0x1000];
AsyncOperation asyncOp = AsyncOperationManager.CreateOperation(null);
Action<Exception> done = e => {
if (completed != null) asyncOp.Post(delegate {
completed(source, destination, e); }, null);
};
AsyncCallback rc = null;
rc = readResult => {
try {
int read = source.EndRead(readResult);
if (read > 0) {
destination.BeginWrite(buffer, 0, read, writeResult => {
try {
destination.EndWrite(writeResult);
source.BeginRead(
buffer, 0, buffer.Length, rc, null);
}
catch (Exception exc) { done(exc); }
}, null);
}
else done(null);
}
catch (Exception exc) { done(exc); }
};
source.BeginRead(buffer, 0, buffer.Length, rc, null);
}
从这篇文章 Article
我未能遵循的是,如何通知代表副本已完成?复制完成后说我想对复制的文件执行操作。
是的,我确实知道这可能超出了我在C#中的几年。
答案 0 :(得分:5)
在
done(exc);
和
else done(null);
位执行Action<Exception>
,后者将使用Action<Stream, Stream, Exception>
参数调用传递给它的completed
。
这是使用AsyncOperation.Post
完成的,以便在适当的线程上执行completed
委托。
CopyStreamToStream(input, output, CopyCompleted);
...
private void CopyCompleted(Stream input, Stream output, Exception ex)
{
if (ex != null)
{
LogError(ex);
}
else
{
// Put code to notify the database that the copy has completed here
}
}
或者你可以使用lambda表达式或匿名方法 - 它取决于你需要多少逻辑。
答案 1 :(得分:2)
委托包含在另一个名为done
的委托中。这会在catch
块中以及else
块中朝AsyncCallback
委托末尾调用,然后传递给BeginRead
:
AsyncCallback rc = null;
rc = readResult => {
try {
int read = source.EndRead(readResult);
if (read > 0) {
destination.BeginWrite(buffer, 0, read, writeResult => {
try {
destination.EndWrite(writeResult);
source.BeginRead(
buffer, 0, buffer.Length, rc, null);
}
catch (Exception exc) { done(exc); } // <-- here
}, null);
}
else done(null); // <-- here
}
catch (Exception exc) { done(exc); } // <-- and here
};
答案 2 :(得分:1)
行done(...)
是代表被引发的地方。代表在代码的早期分配,即
Action<Exception> done = e => {
if (completed != null) asyncOp.Post(delegate {
completed(source, destination, e); }, null);
};
答案 3 :(得分:0)
@ltech - 我可以使用它来复制服务器上的多个文件吗?示例:在for循环中我可以调用此方法,它是否与实例化线程或通过命令模式调用委托移动多个文件相同?