C#跨线程通信 [英] C# Cross-Thread communication

查看:210
本文介绍了C#跨线程通信的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在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:

  1. 在你的窗体添加属性

  1. 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屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆