In a winform you have to make all modification from the thread where the winform is created.
If you manage async operations you'll step into the problem of modifying the form from another thread.
You can use delegate to do this.
Say you want to change the textbox text.
First declare the delegate that accepts a string as a parameter:
public delegate void SetLogTextDelegate(String myString);
Then declare a variable with the previous delegate as hits type.
public SetLogTextDelegate myDelegate;
Implement the method that will be called:
public void SetLogTextMethod(string myString)
{
System.Diagnostics.Trace.WriteLine(myString);
this.txtLog.Text += myString + Environment.NewLine;
}
Actually I use this method to log some messages either in the OutputDebugString (I take the default listener) and in the textbox.
Then assign the delegate (the form constructor is a good place).
myDelegate = new SetLogTextDelegate(SetLogTextMethod);
You can now call the delegate wherever you want:
this.Invoke(this.myDelegate, new object[] { myString });
You can embed this call in a method of his own for clarity sake:
public void SetLogText(string myString)
{
this.Invoke(this.myDelegate, new object[] { myString });
}
A sample winform app:
using System;
using System.Windows.Forms;
using System.Threading;
namespace CrossThreadCallDemo
{
public partial class Form1 : Form
{
public delegate void SetLogTextDelegate(String myString);
public SetLogTextDelegate myDelegate;
public void SetLogText(string myString)
{
this.Invoke(this.myDelegate, new object[] { myString });
}
public void SetLogTextMethod(string myString)
{
System.Diagnostics.Trace.WriteLine(myString);
this.txtLog.Text += myString + Environment.NewLine;
}
public Form1()
{
InitializeComponent();
SetLogTextMethod("Form started threadId=" + Thread.CurrentThread.ManagedThreadId);
myDelegate = new SetLogTextDelegate(SetLogTextMethod);
}
private void btnStart_Click(object sender, EventArgs e)
{
new System.Threading.Thread(new ParameterizedThreadStart(Process)).Start();
}
void Process(object state)
{
//txtLog.Text = "Hello";
if (this.InvokeRequired)
SetLogText("Hello threadId=" + Thread.CurrentThread.ManagedThreadId);
else
txtLog.Text = "Hello";
}
}
}
That's it
posted @ sabato 1 marzo 2008 21:58