Thread syncronisation is required...?  
Author Message
IamHuM





PostPosted: Visual C# General, Thread syncronisation is required...? Top

Hi…

In my application I am using 8 threads. All 8 threads are calling 1 function & in that function I am passing a string & index of thread. According to the index & if that passed string is matched with the string then I am popping a dialog box with thread number… I want my all the threads to call the same function in between their routine…

Does this require thread synchronization… My code is running fine but while debugging its giving error that Cross-Threaded Operation in Invalid…

If thread synchronization is required how I can do that… or if not what is the other way to avoid this exception…

//Sample code - :

void Thread_Handler1()

{

for (; ; )

{

Thread.Sleep(3);

//Do something

string str = CheckAndProcessString("From Thread1");

//Do something

}

}

void Thread_Handler2()

{

for (; ; )

{

Thread.Sleep(3);

//Do something

string str = CheckAndProcessString("From Thread2");

//Do something

}

}

//The thread handler routine contents are common for all other 6 threads

public string CheckAndProcessString(int l_iIndex, string strRxString)

{

// Do something

if(strRxString == "Got the String ")

MessageBox.Show(this, ,"Got the String…on Thread_" + l_iIndex ,"Got the String…",MessageBoxButtons.OK , MessageBoxIcon.Information);

// Do something

}

Thanks & Regards,

Vinay


Visual C#17  
 
 
RizwanSharp





PostPosted: Visual C# General, Thread syncronisation is required...? Top

MessageBox.Show(this, ,"Got the String…on Thread_" + l_iIndex ,"Got the String…",MessageBoxButtons.OK , MessageBoxIcon.Information);

Remove this from the above method and all will be fine, basically Your GUI (Form) was created in the Main thread of the application and when you try to access that in the other threads you get CrossThreadOperationException, So in the above scenerio ypu can simply get rid of this exception by removing this (form's reference).

It has nothing to do with Thread Synchronization....

I hope this will work.

Best Regards,

Rizwan



 
 
vinay.p





PostPosted: Visual C# General, Thread syncronisation is required...? Top

Thanks Rizwan,

Sorry my mistake...Thread handler function should be like this...(Added 1 & 2 as index in function call...)

void Thread_Handler1()

{

for (; ; )

{

Thread.Sleep(3);

//Do something

string str = CheckAndProcessString(1, "From Thread1");

//Do something

}

}

void Thread_Handler2()

{

for (; ; )

{

Thread.Sleep(3);

//Do something

string str = CheckAndProcessString(2, "From Thread2");

//Do something

}

}

Ya error is there only...but i want that MessageBox as Modal...until user press OK button he is not allowed to do anything on many form...but if i remove that form's reference then it becomes non Modal MessageBox & user can continue doing its operation on main form although MessageBox has prompted user for some instruction...(means if i click on main form then this MessageBox will go in background of main form & user can continue its operation with main form ...which i dont want...)

Can i do this with any other way...

Thank,

Vinay


 
 
Peter Ritchie





PostPosted: Visual C# General, Thread syncronisation is required...? Top

You can't communicate with a from created on one thread from another thread. That includes making a message box modal. To make a message box modal it needs to be in the message loop of all the windows that need to be "disabled" while the message box is active.

For this reason, and many others, you should do all your UI on the main thread. If a background thread does something that needs user interaction then it should communicate it back to the main thread so it can updated the UI properly. This can be done with something like EventWaitHandle, etc.

 
 
vinay.p





PostPosted: Visual C# General, Thread syncronisation is required...? Top

Thanks for your reply...

My problem is that according to MessageBox result (say YES or NO) I’ve to return strings from function CheckAndProcessString.

So if one thread calls this function then I have to wait untill user presses any key on that MessageBox to return the string to that thread & then similarly do it for other thread.

So how I can use EventWaitHandle in my case… Will EventWaitHandle will work for me… Or is there is any other way other than this…

Thanks & Regards,

Vinay


 
 
Peter Ritchie





PostPosted: Visual C# General, Thread syncronisation is required...? Top

Sounds like you have several different design conflicts here. One one hand you want to perform multiple tasks in the background. On the other hand you want each of those background tasks to directly interact with the user. If any of your background threads need to interact with the user you have to synchronize that resource (the resource being the direct interaction with the user). Now, you can do this separately from the main thread and simply use a shared object and the lock keyword (or Monitor, if you want a timeout). But, that leaves you with the problem of the MessageBox not being a child main UI and therefore is not modal to that UI (or ensured it's at the top level).

If you want to keep the aspect that multiple running threads occasionally need feedback from the user you'll need to communicate back to the UI thread to present the required UI. This part can be done with a simple callback (the UI thread would pass a delegate to the background threads upon creation). The hard part is communicating the user's selection back to the background thread. The easiest is to simply have the background thread block on the call to the delegate and have the delegate return a result. The callback would perform the required InvokeRequired/Invoke to ensure the call is on the UI thread then return some value (maybe DialogResult). For example:

delegate DialogResult AcquireUserFeedbackDelgate ( );

public DialogResult AcquireUserFeedback ( )

{

if (InvokeRequired)

{

return (DialogResult)this.Invoke(new AcquireUserFeedbackDelgate(AcquireUserFeedback));

}

return MessageBox.Show(this, "Question", "Title", MessageBoxButtons.YesNo);

}

private static void ThreadMethod(object parameter)

{

System.Diagnostics.Debug.WriteLine(System.Threading.Thread.CurrentThread.Name + " Running");

AcquireUserFeedbackDelgate acquireUserFeedbackDelegate = parameter as AcquireUserFeedbackDelgate;

if (acquireUserFeedbackDelegate != null)

{

// Simulate some work.

System.Threading.Thread.Sleep(1000);

DialogResult dialogResult = acquireUserFeedbackDelegate();

System.Diagnostics.Debug.WriteLine(dialogResult);

}

}

And, creating and starting a thread:

System.Threading.Thread thread = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(ThreadMethod));

thread.Name = "background thread";

thread.Start(new AcquireUserFeedbackDelgate(AcquireUserFeedback));

The benefit to this technique is you're using the MessageBox's modality to synchronize access to the user and you don't need to manually synchronize. The background thread doesn't care, it just sits and waits for the UI thread to process it's delegate call (since it can't continue without the user's response). The UI thread blocks on the modal MessageBox.Show() until the user responds and everyone is happy. Expand the delegate and the AcquireUserFeedback method if you need to pass or return more information.



 
 
Peter Ritchie





PostPosted: Visual C# General, Thread syncronisation is required...? Top

A follow-up question: why 8 threads Is this running on a computer with 8 CPUs Creating more than one CPU-bound thread at a time doesn't make processing go faster; it will actually go slightly slower. Multiple threads bound to the same CPU require a context switch whenever one of those threads is given CPU time. Microsoft's Joe Duffy has estimated context switches as costing 2000-8000 cycles. On a 1Ghz computer that 2-8 microseconds per context switch, times 8 threads, times x context switches per second. I don't know at what rate Windows context switches active threads; but on my computer with only Performance Monitor running it shows about 350 context switches occurring per second (which would be almost 3 milliseconds of time spent context switching at 8000 cycles).