C# 3.0 需要解释一下这个代码-c#

C# 3.0 需要解释一下这个代码-c#,c#-3.0,delegates,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)

我一天一天地熟悉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);
公共静态无效CopyStreamToStream(
流源、流目的地、,
行动完成){
字节[]缓冲区=新字节[0x1000];
AsyncOperation asyncOp=AsyncOperationManager.CreateOperation(空);
动作完成=e=>{
if(已完成!=null)asyncOp.Post(委托{
已完成(源,目标,e);},空);
};
异步回调rc=null;
rc=readResult=>{
试一试{
int read=source.EndRead(readResult);
如果(读取>0){
destination.BeginWrite(缓冲区,0,读,写结果=>{
试一试{
destination.EndWrite(writeResult);
来源:beginhead(
buffer,0,buffer.Length,rc,null);
}
捕获(异常exc){done(exc);}
},空);
}
否则完成(空);
}
捕获(异常exc){done(exc);}
};
BeginRead(buffer,0,buffer.Length,rc,null);
}

从这篇文章

我没有注意到的是,如何通知代理副本已完成?比如说,复制完成后,我想对复制的文件执行一个操作


是的,我确实知道,考虑到我在C#的几年时间,这可能超出我的能力。

该委托被另一个委托所包装,名为
done
。这在
catch
块中调用,以及在
AsyncCallback
委托末尾的
else
块中调用,然后传递给
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
};
AsyncCallback rc=null;
rc=readResult=>{
试一试{
int read=source.EndRead(readResult);
如果(读取>0){
destination.BeginWrite(缓冲区,0,读,写结果=>{
试一试{
destination.EndWrite(writeResult);
来源:beginhead(
buffer,0,buffer.Length,rc,null);
}
catch(Exception exc){done(exc);}/

位执行
操作
,该操作将调用使用
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表达式或匿名方法-这取决于您需要多少逻辑。

done(…)
是引发委托的位置。委托在代码的前面分配,即

Action<Exception> done = e => {  
    if (completed != null) asyncOp.Post(delegate {   
        completed(source, destination, e); }, null);  
};  
Action done=e=>{
if(已完成!=null)asyncOp.Post(委托{
已完成(源,目标,e);},空);
};  

@ltech-我可以用它在服务器上复制多个文件吗?例如:在for循环中,我可以调用这个方法吗?它是否与实例化线程或通过命令模式调用委托来移动多个文件相同?

Jon:如果我想通知DB复制完成了,我将如何在代码中设置它?@ltech:您将传入n适当的操作(通知DB)作为
completed
参数的参数。Jon:那么这个更改操作done=e=>{if(completed!=null)asyncOp.Post(委托{completed(source,destination,e);},null);};to action done=e=>{if(completed!=null)asyncOp.Post(委托){已完成(源,目标,e,DBWork());},null);};@ltech:为了其他人的利益,你根本不会改变这个方法。你会将相关的操作传递给它,它会根据是否抛出异常来对成功或失败做出反应。Jon:如果你能提供上面的评论片段,我将不胜感激。
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
    }
}
Action<Exception> done = e => {  
    if (completed != null) asyncOp.Post(delegate {   
        completed(source, destination, e); }, null);  
};