-1

Windows.Forms ソリューションでいくつかのスレッドを作成しています。

また、BrowserControl (うん、それは OAUTH です) も持っています。もちろん、デバッグに関する問題を見つけています -

クロススレッド操作が無効です: コントロール 'xxForm' は、それが作成されたスレッド以外のスレッドからアクセスされました

それでも私は「正しく」呼んでいます

xxForm.Show()

それが呼び出し呼び出しにラップされていることを確認することによって

.Invoke(新しい MethodInvoker())

それでもスレッドの問題が発生します。私は他のすべて(Focus、BringToFront)を行うことができますが、それはショーのエラーです。

さらに、GUI はブラウザーの応答を取得して表示することはありません。VS デバッガーでは、上記のスレッド エラー (バックグラウンド スレッドのアパートメント状態 == MTA) が発生します。EXE として実行すると、同じコードに STA のスレッド アパメントがあり、デバッグ時に GUI が表示されませんが、EXE を直接実行すると、スレッドの問題はなく、ブラウザ コントロールが入力に応答しません。

質問は次のとおりです。

  • VS / EXE で動作が異なるのはなぜですか?
  • VS でデバッグするにはどうすればよいですか?
  • BrowserControl は複数のスレッドで問題なく動作しますか?

アップデート

はい、コードがないことはわかっています。コードが長すぎます。何ができるか見てみます。

また、回答を投稿する前に質問をお読みください。UI スレッドでバックグラウンド スレッドを呼び出しています。それは問題ではありません。これは結果に影響しません。それを推奨する回答に反対票を投じます。

また、いくつかの希望-私は何時間も検索しました。メッセージポンプにリンクされています。メッセージ ポンプが実行されていない限り、DocumentCompleted イベントは受信されません。

更新 2 私が管理するベストは疑似コードです:

プログラム:

 startWorkQueue
 LoadForm (don't show)

スレッド 1:

 addToQueue

スレッド 2:

 readFromQueue
 ShowForm (on occasion)

現在、ShowForm メソッドは Windows.Form コントロールにあります。この中で呼び出しは Invoke を介して行われるため、2 番目のスレッドが ShowForm を呼び出すにもかかわらず、実際の .Show() などの呼び出しは UI スレッド上にあります。

それで、私は何が欠けていますか?クロススレッド例外がある理由がわかりません....

4

2 に答える 2

1

わかりました、何が起こっているのかを知りました。参考のためにここに投稿します。将来誰かに役立つことを願っています。

通常のフォーム アプリケーションに対しては、いくつかの異なる制約がありました。フォームはメイン スレッドで作成されましたが、別のスレッドで Show() が呼び出されました。また、開始 UI もありません。バックグラウンドで待機し、UI プロンプトでイベントに反応することがあります。

このように多くの問題が私たちを襲いました。それらをすべてリストするのではなく、要点を詳しく説明します。

アプリケーション.実行

  • アプリケーションの開始時にフォームを表示しないことにした場合は、スレッドを慎重に検討する必要があります (Form.Show のメモを参照してください)。

Form.Show

  • これは、Load/ctor ではなく、すべてのリソース割り当てなどを行います
  • ハンドル作成・リソース割り当てを行う

ハンドルの作成

  • ハウンド
  • Show(n) が含まれる前に特定の Form プロパティにアクセスしようとすると、ハンドルを手動で作成する必要があります (または例外が作成されます)。

    • と同じくらい簡単if (!IsHandleCreated) { CreateHandle(); }

でも

  • これにより、コントロール/フォームが作成されます
  • したがって、ハンドルの作成を呼び出すスレッドでコントロール/フォームが作成されます
  • これは、メイン関数と同じ UI スレッド (STA) である必要があります

    •そうしないと、多くの奇妙なことが発生します

それで

  • Application.Run をどうするかによって制限されることはありません
  • .Show でプロパティにアクセスできます (ただし、最初にハンドルを作成する必要がある場合があります)。
  • 別のスレッドから Show を呼び出すことはできますが、ハンドルがメイン スレッドでのみ作成されるようにしてください。

必要に応じて、特定の問題の詳細を提供できます。

ログに ManagedThread AND ProcessId を表示したり、MSDN を精査したりするなど、さまざまな支援が行われました。

于 2013-01-07T09:21:07.557 に答える
0

コードを貼り付けていないので、WinForms では UI 要素は UI スレッドでのみアクセスする必要があることを思い出してください。UI スレッド以外の他のスレッドは、UI 要素を直接更新しないでください。

于 2013-01-02T15:52:58.523 に答える