2011-01-03 2 views
3

기본 폼 (PrenosForm)이 있고 Form2를 비동기 적으로 실행하려고합니다.AsyncCallback을 BeginInvoke()에 추가하려고하면 C# 매개 변수 개수가 일치하지 않습니다.

  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()가 대리자를 호출 할 수 있으며 예외가 발생하면 폭탄 처리가 실행되고 UI 스레드에서 예외가 발생한다는 것입니다. 대리자의 BeginInvoke() 메서드는이 작업을 수행하지 않고 EndInvoke()를 호출하는 콜백에서 예외를 다시 발생시킵니다.

매우 혼란 스럽지만, 아마 같은 이름을 사용해서는 안됩니다.

0

전혀 사용하지 마십시오.
다른 스레드에 여러 폼을 표시하는 것은 대단히 나쁜 생각이며 많은 문제를 일으킬 수 있습니다.

Control.BeginInvoke이 콜백 매개 변수를 지원하지 않으므로 두 번째 예제가 작동하지 않습니다.
코드가 세 개의 매개 변수를 사용하여 대리인을 호출하는 것으로 해석됩니다. 배열이고, AsyncCallbacknull입니다.
메서드에서 이러한 매개 변수를 사용하지 않으므로 예외가 발생합니다.

또한 Control.BeginInvoke을 호출하면 백그라운드에서 기능이 실행되지 않습니다. 다음에 메시지 루프에 도달하면 UI 스레드에서 실행됩니다.