1

I have a question about threading.

I have a WPF application, that should show the status of some queries. For this I have created a class, that runs multiple queries in multiple thread (backgroundworker). I've also created an event, so I can react while the queries are running.

    private void cmdStart(object sender, RoutedEventArgs e)
    {
        QuerySetup qs = new QuerySetup();
        //Filling qs with some data
        //...
        SqlProxy sql = new SqlProxy();
        sql.QueryCompleted += new SqlProxy.QueryCompletedEventHandler(sql_QueryCompleted);

        //Starts the backgroundworker
        sql.RunSQL(qs);
    }

    private void sql_QueryCompleted(QueryResult qr)
    {
        lstStatus.Items.Clear();
        lstStatus.Items.Add(qr.RuntimeTotal);
        //... and some more...
    }

Now I get an error message that tells me, that I can't access lstStatus because it's owned by a different thread.

But why? Shouldn't the event be in the same thread as the GUI? How can I solve my problem?

4

3 に答える 3

5

いいえ。
ほとんどの非 UI コンポーネントは、非 UI スレッド (通常は ThreadPool スレッド) でコールバックを発生させます。

Dispactcher.BeginInvokeUI スレッドでコードを実行するために呼び出すことができます。

Dispactcher.BeginInvoke(new Action(delegate {
    ...
}));
于 2012-10-31T14:25:52.377 に答える
2

いいえ、イベントは UI スレッドでは実行されません。

回避するのは簡単ですが、UI スレッドで GUI 要素とやり取りするコードを呼び出す必要があります。

private void sql_QueryCompleted(QueryResult qr)
{
    Dispatcher.BeginInvoke(new Action(() => { 
        lstStatus.Items.Clear();
        lstStatus.Items.Add(qr.RuntimeTotal);
        //... and some more...
    });
}
于 2012-10-31T14:27:36.663 に答える
1

Dispatcher.BeginInvoke は、他のスレッドからのコントロールの更新に常に役立ちます。また、Backgroundworker クラスを使用して DoWork からイベントを発生させる場合、イベント ハンドラは DoWork スレッドで発生します。Backgroundworker の WorkCompleted イベントからイベントを発生させると、Backgroundworker を開始したスレッドで発生し、UI スレッドになる可能性があります (ここでは Dispatcher は必要ありません)。Backgroundworker.ProgressChanged イベントについても同様です。

于 2012-11-01T20:15:04.340 に答える