Asynchronous methods - callback method is never called

Please support our C# advertiser: Intel Parallel Studio Home
Thread Solved

Join Date: Oct 2009
Posts: 26
Reputation: farsen is an unknown quantity at this point 
Solved Threads: 0
farsen farsen is offline Offline
Light Poster

Asynchronous methods - callback method is never called

 
0
  #1
Oct 7th, 2009
Hi.

I have this console based Asynchronous VS project that works fine.
And then i have a remoting project which also works fine. I want to edit the remoting project so it is non-blocking, using asynchronous calls.

I´ve tried different examples, but I cant get it to work. None of them seems to call my callback method back.

Here is the relevant snippets:

The remote object:
  1. ....
  2. public class MultiContainer : MarshalByRefObject, IMultiContainer
  3. {
  4. public string GetClientsList()
  5. {
  6. Thread.Sleep(1000);
  7. return Program.ServerForm.GetClientsList();
  8. }
  9. ....

The client which accesses the remote object with asyn call:
  1. namespace Client
  2. {
  3. public partial class Form1 : Form
  4. {
  5. Server.IMultiContainer mc;
  6. private delegate string Delegate();
  7.  
  8. public Form1()
  9. {
  10. InitializeComponent();
  11. }
  12.  
  13. private void button1_Click(object sender, EventArgs e)
  14. {
  15. mc = new Server.MultiContainer();
  16. Delegate del = new Delegate(mc.GetClientsList);
  17. AsyncCallback callback = new AsyncCallback(Callback);
  18. del.BeginInvoke(callback, null);
  19. }
  20.  
  21. private void Callback(IAsyncResult ar)
  22. {
  23. //this callback method is never called...
  24. Delegate del = (Delegate)((AsyncResult)ar).AsyncDelegate;
  25. richTextBox1.Text = del.EndInvoke(ar);
  26. }
  27. ...

Been sitting with this problem for hours, hope you can help!
Thanks alot
Reply With Quote Quick reply to this message  
Join Date: Feb 2009
Posts: 3,364
Reputation: sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of 
Solved Threads: 606
Sponsor
sknake's Avatar
sknake sknake is offline Offline
.NET Enthusiast
 
0
  #2
Oct 7th, 2009
Maybe the delegate never finishes running.... Have you debugged it? This works:
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Windows.Forms;
  9. using System.Runtime.Remoting.Messaging;
  10.  
  11. namespace daniweb
  12. {
  13. public partial class frmAsync : Form
  14. {
  15. private delegate string Delegate();
  16.  
  17. public frmAsync()
  18. {
  19. InitializeComponent();
  20. }
  21.  
  22. private void button1_Click(object sender, EventArgs e)
  23. {
  24. List<string> clients = new List<string>();
  25. clients.Add("1");
  26. clients.Add("2");
  27. clients.Add("3");
  28. //This is a valid call
  29.  
  30. new Func<string[], string>(DoWork).BeginInvoke(
  31. clients.ToArray(),
  32. new AsyncCallback(CleanupCallback),
  33. null);
  34. //This will throw an exception for demonstration purposes
  35. new Func<string[], string>(DoWork).BeginInvoke(
  36. default(string[]),
  37. new AsyncCallback(CleanupCallback),
  38. null);
  39. }
  40.  
  41.  
  42.  
  43. private static string DoWork(string[] clients)
  44. {
  45. //clients will be null in one call, resulting in an exception. This is intended
  46. Console.WriteLine("Work beginning on " + clients.Length.ToString() + " clients.");
  47. System.Threading.Thread.Sleep(2000);
  48. return string.Join(", ", clients);
  49. }
  50.  
  51. private static void CleanupCallback(IAsyncResult ar)
  52. {
  53. AsyncResult result = (AsyncResult)ar;
  54. Func<string[], string> action = (Func<string[], string>)result.AsyncDelegate;
  55. try
  56. {
  57. string returnValue = action.EndInvoke(ar);
  58. Console.WriteLine("finished : " + returnValue);
  59. }
  60. catch (Exception Ex)
  61. {
  62. Console.WriteLine("An error occured: " + Ex.Message);
  63. }
  64. }
  65.  
  66.  
  67. }
  68. }

Results in:
A first chance exception of type 'System.NullReferenceException' occurred in daniweb.exe
Work beginning on 3 clients.
An error occured: Object reference not set to an instance of an object.
A first chance exception of type 'System.NullReferenceException' occurred in mscorlib.dll
finished : 1, 2, 3

The two red lines were output generate from the callback method. The code sample I posted also shows you how to get the exception, if any, that was thrown in your delegate method performing work.
Scott Knake
Custom Software Development
Apex Software, Inc.
Reply With Quote Quick reply to this message  
Join Date: Oct 2009
Posts: 26
Reputation: farsen is an unknown quantity at this point 
Solved Threads: 0
farsen farsen is offline Offline
Light Poster
 
0
  #3
Oct 7th, 2009
Hi, and thank you for the answer!
Yes i have tried debugging it, and it doesent hang or anything, it just doesent call back.

I´ve tried to insert try catches like this:

The client:
  1. private void button1_Click(object sender, EventArgs e)
  2. {
  3. try
  4. {
  5. mc = new Server.MultiContainer();
  6. Delegate del = new Delegate(mc.GetClientsList);
  7. AsyncCallback callback = new AsyncCallback(Callback);
  8. del.BeginInvoke(callback, null);
  9. }
  10. catch(Exception e1)
  11. {
  12. Console.writeline(e1.ToString());
  13. }
  14. }

the object:
  1. public string GetClientsList()
  2. {
  3. try
  4. {
  5. Thread.Sleep(1000);
  6. }
  7. catch (Exception e1)
  8. {
  9. Console.writeline(e1.ToString());
  10. }
  11. return Program.ServerForm.GetClientsList();
  12. }

.. but that returns nothing either.
Am i doing something wrong here?

Thanks alot for your time
Reply With Quote Quick reply to this message  
Join Date: Feb 2009
Posts: 3,364
Reputation: sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of 
Solved Threads: 606
Sponsor
sknake's Avatar
sknake sknake is offline Offline
.NET Enthusiast
 
0
  #4
Oct 7th, 2009
Create a new project and move enough of your code over to demonstrate the problem. At a glance your code looks OK. Upload your project here once you have moved the code. To upload you can click on "Go Advanced" then "Manage Attachments"
Scott Knake
Custom Software Development
Apex Software, Inc.
Reply With Quote Quick reply to this message  
Join Date: Nov 2008
Posts: 254
Reputation: Antenka has a spectacular aura about Antenka has a spectacular aura about Antenka has a spectacular aura about 
Solved Threads: 65
Antenka's Avatar
Antenka Antenka is offline Offline
Posting Whiz in Training
 
1
  #5
Oct 7th, 2009
Hello.
Isn't this non-stop recursive call to the same function:
  1. public string GetClientsList()
  2. {
  3. try
  4. {
  5. Thread.Sleep(1000);
  6. }
  7. catch (Exception e1)
  8. {
  9. Console.writeline(e1.ToString());
  10. }
  11. return Program.ServerForm.GetClientsList();
  12. }
So what if you can see the darkest side of me?
No one would ever change this animal I have become
Help me believe it's not the real me
Somebody help me tame this animal
Reply With Quote Quick reply to this message  
Join Date: Oct 2009
Posts: 26
Reputation: farsen is an unknown quantity at this point 
Solved Threads: 0
farsen farsen is offline Offline
Light Poster
 
0
  #6
Oct 7th, 2009
Thanks alot Sknake, thats very kind of you!

I have made a new skinny project which should show the problem.
Attached Files
File Type: zip RemoteAsyncTest.zip (93.2 KB, 5 views)
Reply With Quote Quick reply to this message  
Join Date: Oct 2009
Posts: 26
Reputation: farsen is an unknown quantity at this point 
Solved Threads: 0
farsen farsen is offline Offline
Light Poster
 
0
  #7
Oct 7th, 2009
Well it never ends in the catch, so I dont think so?

Originally Posted by Antenka View Post
Hello.
Isn't this non-stop recursive call to the same function:
  1. public string GetClientsList()
  2. {
  3. try
  4. {
  5. Thread.Sleep(1000);
  6. }
  7. catch (Exception e1)
  8. {
  9. Console.writeline(e1.ToString());
  10. }
  11. return Program.ServerForm.GetClientsList();
  12. }
Reply With Quote Quick reply to this message  
Join Date: Feb 2009
Posts: 3,364
Reputation: sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of 
Solved Threads: 606
Sponsor
sknake's Avatar
sknake sknake is offline Offline
.NET Enthusiast
 
0
  #8
Oct 7th, 2009
No it was running but the text was failing to set because of illegal cross-threading calls. This works:
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Runtime.Remoting.Messaging;
  8. using System.Text;
  9. using System.Windows.Forms;
  10.  
  11. namespace RemoteAsyncTest
  12. {
  13. public partial class Form1 : Form
  14. {
  15. private delegate string Delegate();
  16. Server.IMultiContainer mc;
  17.  
  18. public Form1()
  19. {
  20. InitializeComponent();
  21. }
  22.  
  23. private void button1_Click(object sender, EventArgs e)
  24. {
  25. mc = new Server.MultiContainer();
  26. new Delegate(mc.GetClientsList).BeginInvoke(new AsyncCallback(Callback), null);
  27. }
  28.  
  29. private void Callback(IAsyncResult ar)
  30. {
  31. System.Diagnostics.Debugger.Break(); //proves it is called
  32. Delegate del = (Delegate)((AsyncResult)ar).AsyncDelegate;
  33. string s = del.EndInvoke(ar);
  34. richTextBox1.Invoke(new MethodInvoker(
  35. delegate()
  36. {
  37. richTextBox1.Text = s;
  38. }
  39. ));
  40. }
  41. }
  42. }

[edit]

Main Thread: Invokes delegate on another thread
Delegate Thread: runs delegate, runs callback (cant modify UI ctrls on this thread)

You only modify controls from the UI thread. This is accomplished by calling Control.Invoke() as above.
[/edit]
Last edited by sknake; Oct 7th, 2009 at 7:05 pm.
Scott Knake
Custom Software Development
Apex Software, Inc.
Reply With Quote Quick reply to this message  
Join Date: Oct 2009
Posts: 26
Reputation: farsen is an unknown quantity at this point 
Solved Threads: 0
farsen farsen is offline Offline
Light Poster
 
0
  #9
Oct 8th, 2009
That worked
I still wonder though, why it didnt complain in compile or run time about the illegal cross threading.

Anyways, thanks alot Scott!
Reply With Quote Quick reply to this message  
Join Date: Feb 2009
Posts: 3,364
Reputation: sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of 
Solved Threads: 606
Sponsor
sknake's Avatar
sknake sknake is offline Offline
.NET Enthusiast
 
0
  #10
Oct 8th, 2009
It did complain if you looked at your "Output" window in the IDE. As far as I know exceptions thrown from the thread pool are supressed by the runtime. If you manually create a thread and it raises an unhandled exception it will bring your entire application down -- and you can't stop it. So instead of bringing the application down they handle all exceptions from the threadpool in this case. You can re-raise the exception on the callback to "catch" it instead of wrapping your delegate in a try..catch, plus if you're calling a delegate from someone elses code you need a way to handle it. The framers thought of a brilliant way of using remoting to pass the exception to the callback so you don't have to create delegates to wrap delegates for exception handling

Please mark this thread as solved if you have found an answer to your question and good luck!
Scott Knake
Custom Software Development
Apex Software, Inc.
Reply With Quote Quick reply to this message  
Reply

This thread has been marked solved.
Perhaps start a new thread instead?
Message:


Thread Tools Search this Thread



Tag cloud for C#
About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC