尝试将AsyncCallback添加到BeginInvoke()时C#参数计数不匹配

Pun*_*unX 3 c# multithreading invoke

我有主窗体(PrenosForm),我试图异步运行Form2.

  1. 它没有回调委托:

    this.BeginInvoke(cp, new object[] { datoteke, this.treeView1.SelectedNode.FullPath.ToString(), this, efekt }, null); //works  1.
    
    Run Code Online (Sandbox Code Playgroud)
  2. 不适用于回调委托(参数计数不匹配):

     this.BeginInvoke(cp, new object[] { datoteke, this.treeView1.SelectedNode.FullPath.ToString(), this, efekt }, new AsyncCallback(callBackDelegate), null); //doesn't work parameter count mismatch 2.
    
    Run Code Online (Sandbox Code Playgroud)
  3. 如果我这样做,可以使用回调委托:

    cp.BeginInvoke(datoteke, this.treeView1.SelectedNode.FullPath.ToString(), this, efekt, new AsyncCallback(callBackDelegate), null); //works  3.
    
    Run Code Online (Sandbox Code Playgroud)

我的问题是为什么一种方式有效而另一种无效?我是新来的.有人会如此善良地回答我的问题并指出我的错误吗?

 private delegate void copyDelegat(List<ListViewItem> datoteke, string path, PrenosForm forma, DragDropEffects efekt);
 private delegate void callBackDelegat(IAsyncResult a);

 public void doCopy(List<ListViewItem> datoteke, string path, PrenosForm forma, DragDropEffects efekt)
 {
     new Form2(datoteke, path, forma, efekt);
 }

 public void callBackFunc(IAsyncResult a)
 {
     AsyncResult res = a.AsyncState as AsyncResult;
     copyDelegat delegat = res.AsyncDelegate as copyDelegat;
     delegat.EndInvoke(a);
 }

public void kopiraj(List<ListViewItem> datoteke, DragDropEffects efekt)
{


 copyDelegat cp = new copyDelegat(doCopy);
 callBackDelegat callBackDelegate = new callBackDelegat(callBackFunc);
 this.BeginInvoke(cp, new object[] { datoteke, this.treeView1.SelectedNode.FullPath.ToString(), this, efekt }, new AsyncCallback(callBackDelegate), null); //doesn't work parameter count missmatch 2.
 this.BeginInvoke(cp, new object[] { datoteke, this.treeView1.SelectedNode.FullPath.ToString(), this, efekt }, null); //works  1.
 cp.BeginInvoke(datoteke, this.treeView1.SelectedNode.FullPath.ToString(), this, efekt, new AsyncCallback(callBackDelegate), null); //works  3.

}
Run Code Online (Sandbox Code Playgroud)

Han*_*ant 7

这是因为Control.BeginInvoke()与SomeDelegate.BeginInvoke()具有完全不同的签名.虽然它们的方法名称相同,但它们基本上是不同的方法.从根本上说,在运行时工作方式不同,没有比较.

Control.BeginInvoke()接受委托和对象[].铸在石头上.

私有委托SomeDelegate(mumble,foo,bar)自动创建SomeDelegate.BeginInvoke()方法.谁的签名采用这三个参数,加上两个额外的参数,一个回调和一个状态对象.

一个重要的运行时差异是Control.BeginInvoke()可以调用委托,如果它有异常,那么在UI线程上引发异常.委托的BeginInvoke()方法不会这样做,它会在调用EndInvoke()的回调中重新引发异常.

我知道,非常令人费解,也许他们不应该使用相同的名字.