需要对此代码进行说明 - c#

时间:2010-04-14 15:12:34

标签: c#-3.0 delegates

我日复一日熟悉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#中的几年。

4 个答案:

答案 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循环中我可以调用此方法,它是否与实例化线程或通过命令模式调用委托移动多个文件相同?