0

かなり新しい言語であるC#で取り組んでいる大規模なプロジェクトがあります。プロジェクトはGUIに大きく依存しており、表示されるデータはたくさんあります。最近、これまでにない場所でクロススレッドエラーが発生しています。それらが発生したこれらのエラーは簡単に解決されました:

if (logListView.InvokeRequired)
{
      logListView.BeginInvoke(new MethodInvoker(
          () => logListView.Items[logListView.Items.Count - 1].EnsureVisible()));
}
else
{
      logListView.Items[logListView.Items.Count - 1].EnsureVisible();
}

ただし、私の質問は次のとおりです。Windowsフォームオブジェクトにアクセスするたびに、そのメソッドを適用する必要がありますか?特別な場合はありますか?私はマルチスレッドを使用していないので、私の知る限り、これらのエラーが発生する場所は私の制御不能です。たとえば、どのコードがどのスレッドで実行されるかを制御することはできません。C#は、それをすべて独自に実行しています(言語についてはよくわかりません)。GUIを変更する各行にifステートメントを実装することは、非常に不快に思えます。

4

2 に答える 2

1

このコードが必要になるのは、UIスレッドの外部から(つまり、生成したスレッドから)winformコンポーネントにアクセスする場合のみです。コアライブラリには、スレッドを生成するコンポーネントがいくつかあります。たとえば、FileSystemWatcher。Winformsは、それ自体でスレッドを生成するだけでなく、UIスレッドのみを備えています。クロススレッドの問題は、作成したコードまたは使用したライブラリが原因で発生します。

于 2012-08-04T20:51:05.123 に答える
0

コードがGUIスレッドで実行されていない場合にのみ、コードを呼び出す必要があります。

どのコードがどのスレッドで実行されるかを制御できません

はい、できます。GUIスレッドでどのコードが実行されるかについて予測できないことは何もありません。ルールが何であるかを知る必要があります。

コード内のGUIスレッドを使い果たす唯一のコードは、非同期コールバックとして実行されるメソッドです。たとえば、タイマーや非同期Webリクエストなどです。(ただし、はGUIスレッドでイベントをSystem.Windows.Forms.Timer実行します。)Tick

(別のスレッドでコードを実行する方法は他にもありますが、マルチスレッドを使用することに注意してください。)

于 2012-08-04T20:59:53.583 に答える