AsyncCallback Explain why my code is not working

G

Guest

Hello,

I have the following example of AsyncCallback from a C# book which I wanted
to implement in my project:

//Class with AsyncDelegate
public class AsyncProcess
{
public AsyncProcess()
{

}
public delegate int AsynExecuteDelegate(string command);

public System.IAsyncResult BeginExecute(string command,
System.AsyncCallback callBack)
{
//string temp;
AsynExecuteDelegate executeDelegate = new
AsynExecuteDelegate(this.Execute);
return executeDelegate.BeginInvoke(command, callBack, null);
}

public int Execute(string command)
{
System.Diagnostics.Trace.WriteLine(command);
//more code
return 1;
}
}

//Client BeginExecute Call and CallBack
private void button2_Click(object sender, System.EventArgs e)
{
AsyncProcess aPr = new AsyncProcess();
aPr.BeginExecute("Do this", new AsyncCallback(ClientCallBack));

}
private void ClientCallBack(System.IAsyncResult ar)
{
AsyncProcess.AsynExecuteDelegate del =
(AsyncProcess.AsynExecuteDelegate)ar.AsyncState;

int result = del.EndInvoke(ar);
MessageBox.Show(result.ToString());
}
Unfortunately this callback doesn't work, it behaves in a very strange way;
when I stepped through the callback, it looked like .EndInvoke would cause
ClientCallBack to be called again, and 2nd time around when it reached
..EndInvoke it would simply exit the function without returning any value.
Very Strange!

However this callback from code sample on MSDN
http://msdn.microsoft.com/library/d...conasynchronousdelegatesprogrammingsample.asp Seems to work:

using System.Runtime.Remoting.Messaging;
.....
.....

private void ClientCallBack(System.IAsyncResult ar)
{
AsyncProcess.AsynExecuteDelegate del =
(AsyncProcess.AsynExecuteDelegate)((AsyncResult)ar).AsyncDelegate;

int result = del.EndInvoke(ar);
MessageBox.Show(result.ToString());
}
Can someone explain why that is. Why is it requiring AsyncDelegate wich is
part of System.Runtime.Remoting.Messaging namespace, what does Remoting has
to do with AsyncCallbacks?

Thank you
 
G

Guest

Well, According to
http://msdn.microsoft.com/library/d.../html/frlrfsystemruntimeremotingmessaging.asp

<quoute>
System.Runtime.Remoting.Messaging namespace are the AsyncResult class....

The AsyncResult class stores and returns the results of an asynchronous
method call. AsyncResult instances contain the return value, call status, the
delegate used for the call, and the other information about the asynchronous
method call.
</quoute>

It's just strange that they put in Remoting.Messaging namespace .

So now, if anyone has advanced knowledge about async callbacks, can someone
expalin why example from a book wont work while msdn.
To summarazie the difference is 1 line of code:

MSDN Working code:
AsyncProcess.AsynExecuteDelegate del =
(AsyncProcess.AsynExecuteDelegate)((AsyncResult)ar).AsyncDelegate;

Book's Not working code:
AsyncProcess.AsynExecuteDelegate del =
(AsyncProcess.AsynExecuteDelegate)ar.AsyncState;

I will stop taling to myself now :)

Thanks
 
N

Nicholas Paldino [.NET/C# MVP]

Lenn,

You need to use the same delegate instance that made the call to
BeginInvoke to call EndInvoke. If you don't, then the results will not be
correct.

Also, your implementation of BeginInvoke should include a parameter for
state to be passed to it (you pass null, and omit the parameter). This
would fall in line with the pattern that has been established by MS.

Hope this helps.
 
G

Guest

Nicholas Paldino said:
Lenn,

You need to use the same delegate instance that made the call to
BeginInvoke to call EndInvoke. If you don't, then the results will not be
correct.

Also, your implementation of BeginInvoke should include a parameter for
state to be passed to it (you pass null, and omit the parameter). This
would fall in line with the pattern that has been established by MS.

Hope this helps.

Yes, it actually does. I see now, that I didn't follow book's example all
the way, I should've passed the same delegate instance that made the call to
BeginInvoke as a state object, it should've been:

return executeDelegate.BeginInvoke(command, callBack, executeDelegate);

Now original Callback works. MSDN pattern is very interesting... They derive
original .BeginInvoke delegate from AsyncResult cllass. There're so many
different ways to do the same thing in .NET, and it's not clear what's the
most efficient one, I wish MSDN provided more documentation on this.
Thanks for your input!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top