2

正しく機能していない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();

    }

}

この動作とその修正方法を説明してください。

4

3 に答える 3

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"); 
});

それはあなたのために働くでしょう。

于 2013-03-04T20:02:32.017 に答える
2

バックグラウンド スレッドから UI 要素を更新することはできません。 ワーカー スレッドは、UI 要素 (Text プロパティ) にアクセスしようとして例外によって失敗します。そのため、メッセージ ボックスも表示されません。通知メカニズムまたは Dispatcher 呼び出しを使用します (Web には、このような無駄な量の情報があります)。

可能な重複/ヘルプは次のとおりです。

BackgroundWorker を使用して GUI を更新する

バックグラウンド ワーカーまたはイベントから GUI を更新する

于 2013-03-04T20:00:47.263 に答える
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();
    }

この質問を確認してください。お役に立てば幸いです...

于 2013-03-04T20:31:54.470 に答える