C# parameter count mismatch when trying to add AsyncCallback into BeginInvoke()
I have main form (PrenosForm) and I am trying to run Form2 asynchronously.
It works without callback delegate:
this.BeginInvoke(cp, new object[] { datoteke, this.treeView1.SelectedNode.FullPath.ToString(), this, efekt }, null); //works 1.
Doesn't work with callback delegate (parameter count mismatch):
this.BeginInvoke(cp, new object[] { datoteke, this.treeView1.SelectedNode.FullPath.ToString(), this, efekt }, new AsyncCallback(callBackDelegate), null); //doesn't work parameter count mismatch 2.
Works with callback delegate if I do it like this:
cp.BeginInvoke(datoteke, this.treeView1.SelectedNode.FullPath.ToString(), this, efekt, new AsyncCallback(callBackDelegate), null); //works 3.
My quest开发者_开发问答ion is why does one way work and the other doesn't? I'm new at this. Would anyone be so kind as to answer my question and point out my mistakes?
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.
}
It is because Control.BeginInvoke() has a completely different signature from SomeDelegate.BeginInvoke(). While their method names are the same, they are fundamentally different methods. And fundamentally work differently at runtime, there is no comparison.
Control.BeginInvoke() takes a delegate and an object[]. Cast in stone.
private delegate SomeDelegate(mumble, foo, bar) automatically creates a SomeDelegate.BeginInvoke() method. Whose signature takes those three arguments, plus two extra arguments, a callback and a state object.
A significant runtime difference is that Control.BeginInvoke() can call a delegate and if it bombs with an exception then the exception is raised on the UI thread. A delegate's BeginInvoke() method doesn't do this, it re-raises the exception in the callback that calls EndInvoke().
Very confuzzling, I know, maybe they shouldn't have used the same name.
Don't do this at all.
Showing multiple forms on different threads is an extremely bad idea and will end up causing lots of trouble.
Your second example doesn't work because Control.BeginInvoke
doesn't support a callback parameter.
Your code is interpreted as calling a delegate with three parameters; an array, and AsyncCallback
, and null
.
Since your method doesn't take such parameters, an exception is thrown.
Also, calling Control.BeginInvoke
won't run a function in the background; it will run it on the UI thread when it next reaches the message loop.
精彩评论