C#跨线程通信 [英] C# Cross-Thread communication
问题描述
在C#.NET,我写了下面这个简单的后台工作线程:
in C#.NET , I've written the following simple background worker thread:
public class MyBackgrounder
{
public delegate void dlgAlert();
public dlgAlert Alert;
public event EventHandler eventAlert;
Thread trd;
public void Start()
{
if (trd == null || trd.ThreadState == ThreadState.Aborted)
{
trd = new Thread(new ThreadStart(Do));
}
trd.IsBackground = true;
trd.Priority = ThreadPriority.BelowNormal;
trd.Start();
}
void Do()
{
Thread.Sleep(3000);
Done();
}
void Done()
{
if (Alert != null)
Alert();
if (eventAlert != null)
eventAlert(this, new EventArgs());
Kill();
}
public void Kill()
{
if (trd != null)
trd.Abort();
trd = null;
}
}
static class Program
{
[STAThread]
static void Main()
{
MyBackgrounder bg = new MyBackgrounder();
bg.eventAlert += new EventHandler(bg_eventAlert);
bg.Alert = jobDone;
bg.Start();
}
static void bg_eventAlert(object sender, EventArgs e)
{
// here, current thread's id has been changed
}
static void jobDone()
{
// here, current thread's id has been changed
}
}
这只是等待3秒(它的工作),然后引发一个特定的事件或调用一个委托。有没有问题,直到这里,一切工作正常。但是,当我观看了 Thread.CurrentThread.ManagedThreadId ,我看到它的后台线程!也许这是正常的,但我怎么能prevent这种行为?如果你测试了 System.Windows.Forms.Timer 组件并处理其勾选的事件,你可以看到 Thread.CurrentThread.ManagedThreadId 没有发生变化,从主线程ID为别的了。
It just waits for 3 seconds (does its job) and then raises an specified event or calls a delegate. there's no problem until here and everything works fine. But when i watch the 'Thread.CurrentThread.ManagedThreadId' , i see it's the background thread! maybe it's normal , but how can i prevent this behavior? if you test the 'System.Windows.Forms.Timer' component and handle its 'Tick' event , you can see that the 'Thread.CurrentThread.ManagedThreadId' has not been changed from main thread Id to anything else.
我该怎么办?
推荐答案
如果您使用的是Windows窗体,你可以做这样的事情:
If You are using Windows Forms you can do something like this:
-
在你的窗体添加属性
In your Form add property
private readonly System.Threading.SynchronizationContext context;
public System.Threading.SynchronizationContext Context
{
get{ return this.context;}
}
在窗体构造函数中设置属性
In Your Form constructor set the property
this.context= WindowsFormsSynchronizationContext.Current;
使用此属性将它传递给你的后台工作作为一个构造函数的参数。这样,你的员工会知道你的GUI环境。在你的后台工作创建类似的属性。
Use this property to pass it to Your background worker as a constructor parameter. This way your worker will know about your GUI context. Create similar property inside Your background worker.
private readonly System.Threading.SynchronizationContext context;
public System.Threading.SynchronizationContext Context
{
get{ return this.context;}
}
public MyWorker(SynchronizationContext context)
{
this.context = context;
}
更改完成()
方法:
void Done()
{
this.Context.Post(new SendOrPostCallback(DoneSynchronized), null);
}
void DoneSynchronized(object state)
{
//place here code You now have in Done method.
}
在DoneSynchronized你应该总是在你的GUI线程。
In DoneSynchronized You should always be in Your GUI thread.
这篇关于C#跨线程通信的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!