0

私のwpfアプリケーションでは、以下のようにボタンクリックにコードを追加しました:

 private void btn_convert_Click(object sender, RoutedEventArgs e)
 {
    Thread t = new Thread(new ThreadStart(WorkerMethod));
    t.SetApartmentState(ApartmentState.MTA);
    t.IsBackground = true;
    t.Start();
 }

メソッド内WorkerMethod()には、次のようなコードがあります。

btn_convert.Content = "Convert";

この行に到達すると、別のスレッドがこのオブジェクトを所有しているため、呼び出し元のスレッドがこのオブジェクトにアクセスできないため、例外がスローされます。

UI がフリーズするため、Dispatcher を使用したくありません。UI は応答する必要があるため、Dispatcher の呼び出しまたは BeginInvoke を選択していません。

貴重なご意見をお聞かせください。

4

2 に答える 2

7

UIがフリーズするため、Dispatcherを使用したくありません。UIはレスポンシブである必要があるため、Dispatcherの呼び出しまたはBrginInvokeを選択しません。

これは、ディスパッチャをひどく使用したことを示しています。

UIスレッドからUIにアクセスする必要があります。WorkerMethodこれは、全体をUIスレッドで実行する必要があるという意味ではありませんが、次の行は次のとおりです。

btn_convert.Content = "Convert";

間違いなくそうです。したがって、スレッドを開始するための現在のコードを保持したい場合がありますが(実際にはアパートメントの状態を設定する必要がありますか)、ディスパッチャーを使用するようにUIにアクセスするコードを変更します。例えば:

Action setButtonContentAction = () => btn_convert.Content = "Convert";
Dispatcher.BeginInvoke(setButtonContentAction);

または、実行している内容によってWorkerThreadは(C#5を使用している場合) 、新しい非同期機能を使用することもできます。これにより、UIスレッドでのUIの動作を維持しやすくなりますが、他に何が起こっているかによって異なります。

于 2013-03-15T07:19:25.513 に答える
1

UI の変更は、メイン スレッドによってのみ適用できます。メイン スレッド呼び出しが必要かどうかを確認できます。

if (btn_convert.InvokeRequired)
{
  btn_convert.Invoke((MethodInvoker)(() => btn_convert.Content = "Convert"));
}
于 2013-03-15T07:20:36.080 に答える