Несоответствие количества параметров в C # при попытке добавить AsyncCallback в BeginInvoke () - PullRequest
3 голосов
/ 04 января 2011

У меня есть основная форма (PrenosForm), и я пытаюсь запустить Form2 асинхронно.

  1. Работает без делегата обратного вызова:

    this.BeginInvoke(cp, new object[] { datoteke, this.treeView1.SelectedNode.FullPath.ToString(), this, efekt }, null); //works  1.
    
  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.
    
  3. Работает с делегатом обратного вызова, если я делаю это следующим образом:

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

Мой вопрос: почему один способ работает, а другой нет?Я новичок в этом.Будет ли кто-нибудь так любезно ответить на мой вопрос и указать на мои ошибки?

 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.

}

Ответы [ 2 ]

7 голосов
/ 04 января 2011

Это потому, что Control.BeginInvoke () имеет совершенно другую подпись, чем SomeDelegate.BeginInvoke ().Хотя их имена методов совпадают, они принципиально разные методы.И принципиально работают по-другому во время выполнения, нет никакого сравнения.

Control.BeginInvoke () принимает делегат и объект [].Литые в камне.

закрытый делегат SomeDelegate (mumble, foo, bar) автоматически создает метод SomeDelegate.BeginInvoke ().Чья сигнатура принимает эти три аргумента, плюс два дополнительных аргумента, обратный вызов и объект состояния.

Существенное различие во время выполнения состоит в том, что Control.BeginInvoke () может вызывать делегат и, если он бомбитс исключением, тогда исключение возбуждается в потоке пользовательского интерфейса.Метод BeginInvoke () делегата не делает этого, он повторно вызывает исключение в обратном вызове, который вызывает EndInvoke ().

Очень сбивает с толку, я знаю, возможно, им не следовало использовать одно и то же имя.

0 голосов
/ 04 января 2011

Не делайте этого вообще.
Отображение нескольких форм в разных потоках - очень плохая идея, и в конечном итоге это вызовет массу проблем.

Ваш второй пример не работает, поскольку Control.BeginInvoke не поддерживает параметр обратного вызова.
Ваш код интерпретируется как вызов делегата с тремя параметрами;массив, AsyncCallback и null.
Поскольку ваш метод не принимает такие параметры, возникает исключение.

Кроме того, вызов Control.BeginInvoke не будет запускать функцию вфон;он запустит его в потоке пользовательского интерфейса, когда в следующий раз достигнет цикла сообщений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...