943,937 Members | Top Members by Rank

Ad:
  • C# Discussion Thread
  • Marked Solved
  • Views: 1168
  • C# RSS
Oct 24th, 2009
0

understanding threading and calling methods

Expand Post »
I have a class that in one of its methods creates a new thread that makes some http requests, serializes the results, packs them up in an event object and then it Should call broadcast an event returning its data. but I can't figure out how.

the class is not a form, so it doesn't have the invoke method, and I need to pass data back to the class. I'm stuck on this.

here is a stripped down version

class someclass
{
       public someclass()
      {

       }
//my event
     public delegate void onTimelineHandler(object sender ,TimelineArgs e);
     public event onTimelineHandler OnTimelineRecieved;

        private void TimelineAsyncStart(string url)
        {
            Thread myAsyncer = new Thread(new ParameterizedThreadStart(doTimelineAsync));

            string[] objar = new string[] { url, username, password };
            myAsyncer.Start(objar);
            
        }

 private void doTimelineAsync(object objar)
        {

            string[] sa2 = (string[])objar;
            string url = sa2[0];
            string username = sa2[1];
            string password = sa2[2];

          //some stuff happens here

             TimelineArgs targs = new TimelineArgs(myobject);

          //here I need to call the event on the class that created    this thread, passing to that event the TImelineArgs object.

        }


]

I could really use some help on this, threading is not my things, I learned using background worker, guess I could have done that here, but really i would like to know how this is done.
Last edited by Diamonddrake; Oct 24th, 2009 at 12:40 am.
Similar Threads
Reputation Points: 442
Solved Threads: 89
Master Poster
Diamonddrake is offline Offline
721 posts
since Mar 2008
Oct 24th, 2009
0
Re: understanding threading and calling methods
If the receivers of the event absolutely must have the information back into thier own thread (like a Windows App sometimes does) then you would handle the invoke for arguments in those receiving threads.
Move your delegate out into the name space so that receivers outside of this class can use it. Really your choice, they can use fully qualified naming to get to it as well.

When the thread is ready to push the data into the event, then check to see if it is assigned, and then call it.

The receiver needs to check to see if invoke is required. Your Something class may itself be called from another thread, so to be safe, let the receivers deal with it.
(see more below this code snip)

C# Syntax (Toggle Plain Text)
  1. using System.Threading;
  2.  
  3. namespace WindowsFormsApplication1
  4. {
  5. public delegate void onTimelineHandler(object sender, TimelineArgs e);
  6. class SomeClass
  7. {
  8. public SomeClass() { }
  9. public event onTimelineHandler OnTimelineRecieved;
  10.  
  11. public void TimelineAsyncStart(string url)
  12. {
  13. Thread myAsyncer = new Thread(new ParameterizedThreadStart(doTimelineAsync));
  14. string[] objar = new string[] { url, "username", "password" };
  15. myAsyncer.Start(objar);
  16. }
  17.  
  18. private void doTimelineAsync(object objar)
  19. {
  20. string[] sa2 = (string[])objar;
  21. string url = sa2[0];
  22. string username = sa2[1];
  23. string password = sa2[2];
  24. object myobject = "411"; // just something to play with
  25. //some stuff happens here
  26. if( OnTimelineRecieved != null )
  27. {
  28. TimelineArgs targs = new TimelineArgs(myobject);
  29. OnTimelineRecieved(null, targs);
  30. }
  31. }
  32. }
  33.  
  34. public class TimelineArgs
  35. {
  36. public object Something = null;
  37. public TimelineArgs(object something)
  38. {
  39. Something = something;
  40. }
  41. }
  42.  
  43. }

If the receivers need to invoke it, then use something like this:
C# Syntax (Toggle Plain Text)
  1. void cs_OnTimelineRecieved(object sender, TimelineArgs e)
  2. {
  3. if ( this.InvokeRequired )
  4. {
  5. onTimelineHandler d = new onTimelineHandler(cs_OnTimelineRecieved);
  6. this.Invoke(d, new object[] { sender, e });
  7. }
  8. else
  9. {
  10. string something = e.Something.ToString();
  11. MessageBox.Show(something);
  12. }
  13. }

I work with many threads in an app, and they exchange information all the time without invoke. It is when I need to update a some non-thread safe object that I need to use Invoke.

Hope this helps,
Jerry
Reputation Points: 69
Solved Threads: 75
Posting Pro in Training
JerryShaw is offline Offline
465 posts
since Nov 2006
Oct 24th, 2009
0
Re: understanding threading and calling methods
I managed to get it to work. I honestly really don't understand *how* it works, but I can implement the code behind doing it.

start()
{
Func<Params, paramsreturnValue> method = Methodname;
IAsyncResult res = method.BeginInvoke(Params, Params, new AsyncCallback(methodthatCatchesEndInvoke), IDK object);
}

methodthatCatchesEndInvoke(IAsyncResult res)
{
ReturnValue answer = method.EndInvoke(res);
}

I don't know any other way to do this. This works well, only problem is that you have to invoke the result again before you can even use it. And that makes it a lot of work to use. If anyone knows how to get around that. i would appreciate more information.
Reputation Points: 442
Solved Threads: 89
Master Poster
Diamonddrake is offline Offline
721 posts
since Mar 2008
Oct 24th, 2009
0
Re: understanding threading and calling methods
Thanks jerry, but calling the event from the 2nd thread always fails in my code. but I guess its because I haven't disabled the cross thread warnings.

I really don't like having to check if an invoke is required in the event handler on the form, I know an Invoke will always be required because that events exists in my code for the sole reason of threading. But I don't know how to get around it.

as I posted above, I did find a way to just run the methods asynchronously easy returning the data. but I still have the problem of having to invoke the response data in order to use it and I wish there was a way around it.
Reputation Points: 442
Solved Threads: 89
Master Poster
Diamonddrake is offline Offline
721 posts
since Mar 2008
Oct 24th, 2009
0
Re: understanding threading and calling methods
I think you are stuck with Invoke because that is how C# moves the object pointer into the memory stack of the thread that wants to use it.
A little trick on sending the event to something that does not know how to check for InvokeRequired is to replace sender with null, and check that when it hits the handler. Replace sender in the delegate with this, or some non null value so it knows not to re-throw the invoke.

Good Luck

Thanks jerry, but calling the event from the 2nd thread always fails in my code. but I guess its because I haven't disabled the cross thread warnings.

I really don't like having to check if an invoke is required in the event handler on the form, I know an Invoke will always be required because that events exists in my code for the sole reason of threading. But I don't know how to get around it.

as I posted above, I did find a way to just run the methods asynchronously easy returning the data. but I still have the problem of having to invoke the response data in order to use it and I wish there was a way around it.
Reputation Points: 69
Solved Threads: 75
Posting Pro in Training
JerryShaw is offline Offline
465 posts
since Nov 2006
Oct 24th, 2009
0
Re: understanding threading and calling methods
Jerry -- I'm not knocking on your example, it was great, I just wanted to point one thing out:
C# Syntax (Toggle Plain Text)
  1. if( OnTimelineRecieved != null )
  2. {
  3. TimelineArgs targs = new TimelineArgs(myobject);
  4. OnTimelineRecieved(null, targs);
  5. }

Technically some believe that is not "thread safe" because in the time between checking if the event is not null and calling it someone in another thread could null it -- resulting in a null reference exception. Likewise the events are usually being null'd when the object is being disposed and the event shouldn't be called anyway -- which will likely result in another exception somewhere else in the code. I just wanted to throw that in there.

The "recommended way" or "best practices" way to call a delegate:
C# Syntax (Toggle Plain Text)
  1. public event EventHandler SomeEvent;
  2. private void SampleEvent()
  3. {
  4. var del = this.SomeEvent;
  5. if (del != null)
  6. del(this, new EventArgs());
  7. }


Diamonddrawe,
I have posted a bit of code that holds an HTTP connection open and fires off an event as it receives data. The code is posted here:
http://www.daniweb.com/forums/post10...ml#post1024173

That code fires off an event from the thread pool so it needs to be invoked back on to the GUI thread, just as Jerry mentioned and demonstrated. I handled it very similarly to the way he did:
C# Syntax (Toggle Plain Text)
  1. void reader_OnLineReceived(object sender, TwitterLineReceivedArgs e)
  2. {
  3. this.Invoke(new MethodInvoker(
  4. delegate()
  5. {
  6. System.Threading.Interlocked.Increment(ref linesRead);
  7. textBox1.Text += e.Line;
  8. label1.Text = string.Format("Lines Read: {0:F0}", linesRead);
  9. }
  10. ));
  11. }

In this case I didn't check for InvokeRequired since I know that event will always be called from another thread.

I hope this helps out some. If it didn't then try uploading a project so we can take a look.
Featured Poster
Reputation Points: 1749
Solved Threads: 735
Senior Poster
sknake is offline Offline
3,948 posts
since Feb 2009
Oct 24th, 2009
0
Re: understanding threading and calling methods
One more thing.... is there any reason you were manually creating a thread instead of using the thread pool?
C# Syntax (Toggle Plain Text)
  1. Thread myAsyncer = new Thread(new ParameterizedThreadStart(doTimelineAsync));

I noticed in a later post you switched over to using .BeginInvoke() which is probably the way I would approach it. Creating your own thread can guarantee execution where as the ThreadPool queues up software threads until it has time for execution. If you manually create a thread that is not marked as a background thread it will also stop your application from closing until that thread has been aborted.
Featured Poster
Reputation Points: 1749
Solved Threads: 735
Senior Poster
sknake is offline Offline
3,948 posts
since Feb 2009
Oct 24th, 2009
0
Re: understanding threading and calling methods
Thanks,

firstly, I manually created the thread because I have no Idea what I am doing. Threading is so new to me. I have used the backgroundworker class before, as it handles it all for you and even accepts and returns and object by default. but I needed a direct implementation any my gui was freezing during http requests.

you know, I never did get that whole anonymous delegate thing, so I still invoke on my main thread's event handler using

C# Syntax (Toggle Plain Text)
  1. this.Invoke(new UpdateTextCallback(this.UpdateText), new object[] { e.TimeLine_Statuses });
  2.  
  3. then create a delegate and a method
  4.  
  5. public delegate void UpdateTextCallback(statuses text);
  6.  
  7. private void UpdateText(statuses text)
  8. { statuses twitStatuses = text;
  9.  
  10. foreach (statusesStatus stats in twitStatuses.status)
  11. {
  12. richTextBox1.Text = richTextBox1.Text + "\n" + stats.text + " - user: " + stats.user[0].name;
  13. }
  14. }

but I will try that anonymous approach.

Also, I didn't really understand why in your link that you only did the read response stream in Async and not the entire request. But either way I needed more, my http request ironically also a twitter api wrapper, makes a request for a user's "friendtimeline" and receives the xml, then deserializes it based on a schema class and returns that "statuses" object to the UI where it can easily get any information about the post.

I got both the synchronous and Asynchronous methods in my class when I get to using it in my newest hobby project I will be able to choose which best suits my needs.

I have gotten it working, just that whole invoke delegate with a callback thing on the form that I don't like.

question! Would calling the event from a delegate not require me to invoke the event data on the GUI thead?
C# Syntax (Toggle Plain Text)
  1. public event EventHandler SomeEvent;
  2. private void SampleEvent()
  3. {
  4. var del = this.SomeEvent;
  5. if (del != null)
  6. del(this, new EventArgs());
  7. }

and thanks again for all the handy info.
Reputation Points: 442
Solved Threads: 89
Master Poster
Diamonddrake is offline Offline
721 posts
since Mar 2008
Oct 24th, 2009
0
Re: understanding threading and calling methods
No .. You can call any method from any thread. The problem is that if the code implemented and subscribed to that delegate modify a control on the GUI thread .. and the delegate is called from another thread. It is up to the person implementing the code subscribed to the event to handle cross-thread calls.

>>Also, I didn't really understand why in your link that you only did the read response stream in Async and not the entire request

The reason I did this is how the exception would surface. The way I implemented it will cause an exception to be thrown if the request could not be opened. I wanted to block the caller until the connection opened. Calling .Start() and having it throw an exception is much "cleaner" (in my mind at least) than calling .Start() then having it execute OK just to fire off an error delegate immediately.

>>I got both the synchronous and Asynchronous methods in my class when I get to using it in my newest hobby project I will be able to choose which best suits my needs.

If you carefully design an asynchronous code base for your twitter API you could easily convert it to synchronous on the surface by blocking calls until your async calls fire
Featured Poster
Reputation Points: 1749
Solved Threads: 735
Senior Poster
sknake is offline Offline
3,948 posts
since Feb 2009
Oct 25th, 2009
0
Re: understanding threading and calling methods
Quote ...
If you carefully design an asynchronous code base for your twitter API you could easily convert it to synchronous on the surface by blocking calls until your async calls fire
I developed it synchronously first just to get the twitter api calls right, then I just added extra methods to the class to handle it Asynchronously, and I'm really satisfied with that. Now I just have to extend the class to all the other API calls...

although I'm not sure the way I have started it is the best way to go about it, might have been better to have a twitter object that created child objects of each general subject from the API (user_timeline, Friends_timeline, Status, Update, ect) and put the code fore each different part in there, so that way using the code would be much more organized.
Reputation Points: 442
Solved Threads: 89
Master Poster
Diamonddrake is offline Offline
721 posts
since Mar 2008

This thread is solved

Either the thread starter or a moderator has marked this thread as solved. You can most likely trust the responses and answers given. There is most likely no reason for any further responses to be posted here. If you have a related question, please start a new thread in this forum instead.

This thread is more than three months old

No one has posted to this discussion for at least three months. Please let old threads die and do not reply to them unless you feel you have something new and valuable to contribute that absolutely must be added to make the discussion complete. Otherwise, please start a new thread in this forum instead.
Message:





About Us | Contact Us | Advertise | Acceptable Use Policy
Forum Index | Build Custom RSS Feed


Follow us on Twitter


© 2011 DaniWeb® LLC