Could someone please help me with the following problem:
There are two classes MainForm and LWriter. Below is a method from the LWriter that in addition to writing
Interactions with UI controls must be done on the UI thread. You can build the string on a background thread, but you should use Control.Invoke or Control.BeginInvoke to marshal to the UI thread before interacting with it.
Lots of examples of this on the net and stack overflow.
delegate
can be used for Thread safe calls
Check this http://msdn.microsoft.com/en-us/library/ms171728.aspx
// This delegate enables asynchronous calls for setting
// the text property on a TextBox control.
delegate void SetTextCallback(string text);
// This method demonstrates a pattern for making thread-safe
// calls on a Windows Forms control.
//
// If the calling thread is different from the thread that
// created the TextBox control, this method creates a
// SetTextCallback and calls itself asynchronously using the
// Invoke method.
//
// If the calling thread is the same as the thread that created
// the TextBox control, the Text property is set directly.
private void SetText(string text)
{
// InvokeRequired required compares the thread ID of the
// calling thread to the thread ID of the creating thread.
// If these threads are different, it returns true.
if (this.textBox1.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });
}
else
{
this.textBox1.Text = text;
}
}
As suggested by Sonu, delegate
can be used for Thread safe calls, and you can use Linq to shorten the code:
this.BeginInvoke( (Action) delegate ()
{
//code to update UI
});
See this link for more information.
Typically you should run this kind of time-consuming operations in a BackgroundWorker
. Define a work method:
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
// execute your WriteOutput method
}
and set is as the DoWork
event handler:
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += new DoWorkEventHandler(worker_DoWork);
worker.RunWorkerAsync(); // start the worker
To safely update the UI from a different thread use the Control.BeginInvoke
method:
mainForm.BeginInvoke(
() => { mainForm.UpdateLog(<text>); });