| | |
understanding threading and calling methods
Please support our C# advertiser: Intel Parallel Studio Home
Thread Solved |
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
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.
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; 32 Days Ago at 12:40 am.
•
•
Join Date: Nov 2006
Posts: 436
Reputation:
Solved Threads: 72
0
#2 32 Days Ago
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)
If the receivers need to invoke it, then use something like this:
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
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)
using System.Threading; namespace WindowsFormsApplication1 { public delegate void onTimelineHandler(object sender, TimelineArgs e); class SomeClass { public SomeClass() { } public event onTimelineHandler OnTimelineRecieved; public 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]; object myobject = "411"; // just something to play with //some stuff happens here if( OnTimelineRecieved != null ) { TimelineArgs targs = new TimelineArgs(myobject); OnTimelineRecieved(null, targs); } } } public class TimelineArgs { public object Something = null; public TimelineArgs(object something) { Something = something; } } }
If the receivers need to invoke it, then use something like this:
C# Syntax (Toggle Plain Text)
void cs_OnTimelineRecieved(object sender, TimelineArgs e) { if ( this.InvokeRequired ) { onTimelineHandler d = new onTimelineHandler(cs_OnTimelineRecieved); this.Invoke(d, new object[] { sender, e }); } else { string something = e.Something.ToString(); MessageBox.Show(something); } }
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
0
#3 32 Days Ago
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.
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.
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.
0
#4 32 Days Ago
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.
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.
•
•
Join Date: Nov 2006
Posts: 436
Reputation:
Solved Threads: 72
0
#5 32 Days Ago
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
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.
0
#6 32 Days Ago
Jerry -- I'm not knocking on your example, it was great, I just wanted to point one thing out:
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:
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:
In this case I didn't check for
I hope this helps out some. If it didn't then try uploading a project so we can take a look.
C# Syntax (Toggle Plain Text)
if( OnTimelineRecieved != null ) { TimelineArgs targs = new TimelineArgs(myobject); OnTimelineRecieved(null, targs); }
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)
public event EventHandler SomeEvent; private void SampleEvent() { var del = this.SomeEvent; if (del != null) del(this, new EventArgs()); }
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)
void reader_OnLineReceived(object sender, TwitterLineReceivedArgs e) { this.Invoke(new MethodInvoker( delegate() { System.Threading.Interlocked.Increment(ref linesRead); textBox1.Text += e.Line; label1.Text = string.Format("Lines Read: {0:F0}", linesRead); } )); }
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.
0
#7 32 Days Ago
One more thing.... is there any reason you were manually creating a thread instead of using the thread pool?
I noticed in a later post you switched over to using
C# Syntax (Toggle Plain Text)
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. 0
#8 32 Days Ago
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
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?
and thanks again for all the handy info.
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)
this.Invoke(new UpdateTextCallback(this.UpdateText), new object[] { e.TimeLine_Statuses }); then create a delegate and a method public delegate void UpdateTextCallback(statuses text); private void UpdateText(statuses text) { statuses twitStatuses = text; foreach (statusesStatus stats in twitStatuses.status) { richTextBox1.Text = richTextBox1.Text + "\n" + stats.text + " - user: " + stats.user[0].name; } }
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)
public event EventHandler SomeEvent; private void SampleEvent() { var del = this.SomeEvent; if (del != null) del(this, new EventArgs()); }
and thanks again for all the handy info.
0
#9 31 Days Ago
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
>>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
0
#10 31 Days Ago
•
•
•
•
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
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.
![]() |
Similar Threads
- c++ calling a dll (C++)
- calling methods using variables (Python)
- stumped on java homework (Java)
- Problem with thread and Pyro (Python)
- calling function from one object to another object's function (C++)
- VB.NET Threading or Backgroundworker ?? Struggling to get them to work (VB.NET)
- Declaring and identifying methods (Java)
- Basic problem calling methods within a class (Java)
- calling methods. (Java)
Other Threads in the C# Forum
| Thread Tools | Search this Thread |







