2011-01-03 2 views
3

У меня есть основная форма (PrenosForm), и я пытаюсь запустить Form2 асинхронно.Нечеткое совпадение параметров C# при попытке добавить AsyncCallback в BeginInvoke()

  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. 

} 

ответ

7

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

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

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

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

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

0

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

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

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

Смежные вопросы