我有一个带有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();
}
}
请解释一下这种行为以及如何解决?
答案 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调用(网上有大量类似的信息)
以下是可能的重复/帮助:
答案 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问题,希望可以帮助...