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

查看:25
本文介绍了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' 时,我发现它是后台线程!也许这很正常,但我怎样才能防止这种行为?如果您测试 'System.Windows.Forms.Timer' 组件并处理其 'Tick' 事件,您可以看到 '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;
    }
    

  • 改变你的 Done() 方法:

    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天全站免登陆