事件没有在表格中正确提升

时间:2013-03-04 19:57:35

标签: c# .net wpf multithreading events

我有一个带有eventhandler的MainWindow,它无法正常工作。我已经制作了这个问题的简单模型。请在代码中查看问题所在的注释:

public partial class MainWindow : Window
{
    public event EventHandler Event1;

    public MainWindow()
    {
        Event1 += MainWindow_Event1;
        InitializeComponent();
    }

    void MainWindow_Event1(object sender, EventArgs e)
    {
        textBox1.Text = "wth!?";  //Not changing text box. Not showing message. If delete this line, it will work fine
        MessageBox.Show("raised");  
    }

    private void bw_DoWork(object sender, DoWorkEventArgs e)
    {
        EventHandler evt = Event1;
        while (true)
        {
            Thread.Sleep(500);
            evt(null, null);
        }
    }

    private void Button_Click_1(object sender, RoutedEventArgs e)
    {
        BackgroundWorker bw = new BackgroundWorker();
        bw.DoWork += bw_DoWork;
        bw.RunWorkerAsync();

    }

}

请解释一下这种行为以及如何解决?

3 个答案:

答案 0 :(得分:3)

问题是你是从后台线程调用事件的。这不起作用,程序只是在尝试访问TextBox时挂起。但是,如果您更改此代码:

textBox1.Text = "wth!?";  //Not changing text box. Not showing message. If delete this line, it will work fine
MessageBox.Show("raised"); 

到此:

this.Dispatcher.BeginInvoke((Action)delegate()
{
    textBox1.Text = "wth!?";  //Not changing text box. Not showing message. If delete this line, it will work fine
    MessageBox.Show("raised"); 
});

它对你有用。

答案 1 :(得分:2)

您无法从后台线程更新UI元素。 工作线程因尝试访问UI元素(Text属性)而异常失败。所以messageBox也没有显示出来。使用通知机制或Dispatcher调用(网上有大量类似的信息)

以下是可能的重复/帮助:

Update GUI using BackgroundWorker

Update GUI from background worker or event

答案 2 :(得分:1)

这个问题是因为您需要使用当前线程的同步上下文来进行线程之间的通信,这样的事情

private void Button_Click(object sender, RoutedEventArgs e)
    {
        var sync = SynchronizationContext.Current;
        BackgroundWorker w = new BackgroundWorker();
        w.DoWork+=(_, __)=>
            {  
                //Do some delayed thing, that doesn't update the view
                sync.Post(p => { /*Do things that update the view*/}, null);
            };
        w.RunWorkerAsync();
    }

请检查this问题,希望可以帮助...

相关问题