jccorner Posted August 10, 2007 Posted August 10, 2007 I'm fairly amazed that I'm having trouble finding some code to do this. So I'm asking my fellow programmers. Here's my situation: my windows program currently has one form and several classes which each run a thread that performs specific tasks including downloading a csv file from an ftp site and consumes it into a sql server db or checks the time and performs a stored procedure which will kick off some other tasks, etc. Now certain events/errors may occur in these threads. My issue is that I create a new class and then start the thread, but am having problems when I want to send a message from the thread class to the form when an event or error occurs. I can't invoke a method from the class and the form has no idea when an event occurs in the class. So, I'm stuck on where I should be going to accomplish this since multiple threads can be running on the form at once. I know I can create a form for each thread class, but want to try to utilize one form and not have to look at three different forms to see what the thread is doing. Thanks for any assistance. Quote Applying computer technology is simply finding the right wrench to pound in the correct screw
MrPaul Posted August 10, 2007 Posted August 10, 2007 Events and delegates I can't invoke a method from the class and the form has no idea when an event occurs in the class. One solution - have the class raise events which the form can handle: //In the class public event EventHandler<EventArgs> ErrorOccurred; private void ThreadProc() { try { //Do some processing } catch (Exception e) { //An error occurred - raise the event if (ErrorOccurred != null) ErrorOccurred(this, EventArgs.Empty); } } //In the form private void MyMethod() { MyClass c1 = new MyClass(); //Attach to event c1.ErrorOccurred += c1_ErrorOccurred; c1.Start(); } //Handler for the ErrorOccurred event private void c1_ErrorOccurred(object sender, EventArgs e) { if (InvokeRequired) { //Marshal the event to the form's UI thread Invoke(new EventHandler<EventArgs>(c1_ErrorOccurred), sender, e); return; } //Act on the error - in this case, just show a message box MessageBox.Show("An error occurred while processing c1"); } Here, the class MyClass exposes an event ErrorOccurred which the form can attach itself to in order to receive notification of an error. In the event handler, the call is marshalled to the UI thread using Invoke, so that there are no problems interacting with the form controls and UI elements. I've used the EventHandler<EventArgs> delegate but you can define your own delegate which better matches the information you wish to pass to the form. I like to define my own EventArgs subclass with properties for all relevant event information. Good luck :cool: Quote Never trouble another for what you can do for yourself.
jccorner Posted August 10, 2007 Author Posted August 10, 2007 MrPaul, then to send say e.Message then I should use a delegate?? Quote Applying computer technology is simply finding the right wrench to pound in the correct screw
MrPaul Posted August 11, 2007 Posted August 11, 2007 Custom delegate Okay, so lets first define a delegate which takes a string parameter: public delegate void MyEventHandler(string exMessage); Then, in the class, define an event of type MyEventHandler: public event MyEventHandler ErrorOccurred; private void ThreadProc() { try { //Do some processing } catch (Exception e) { //An error occurred - raise the event if (ErrorOccurred != null) ErrorOccurred(e.Message); } } And in the form, implement a method with the same signature as the delegate, and attach it to the event: //In the form private void MyMethod() { MyClass c1 = new MyClass(); //Attach to event c1.ErrorOccurred += c1_ErrorOccurred; c1.Start(); } //Handler for the ErrorOccurred event private void c1_ErrorOccurred(string exMessage) { if (InvokeRequired) { //Marshal the event to the form's UI thread Invoke(new MyEventHandler(c1_ErrorOccurred), exMessage); return; } //Act on the error - in this case, just show a message box MessageBox.Show("An error occurred while processing c1:\n\n" + exMessage); } Hope this gives you some idea. :) Quote Never trouble another for what you can do for yourself.
jccorner Posted August 13, 2007 Author Posted August 13, 2007 Certainly does, thank you very much MrPaul. Quote Applying computer technology is simply finding the right wrench to pound in the correct screw
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.