2011-12-23 9 views
0

この長い投稿は大変申し訳ありません。私はC#wpfの問題についていくつかの助けが必要です。私は複雑なUI(何とか)を構築しており、スタートやストップなどのボタンがいくつかあります。長い処理を実行するWPFユーザーインターフェイスがハングアップする

私がスタートボタンをクリックすると、実行プロセスはいくつかのプロトコルレイヤーなどとの通信から始まり、長いプロセスです。このプロセスでは、「テキストを入力」、「選択」 Something "など...私はいくつかのwpfウィンドウオブジェクトを表示する必要があります...今度は、私は自動的にウィンドウを破壊し、再度処理する必要があります。

まず、メインウィンドウクラスで実行を実行しようとしました。しかし、実行が開始されると、ユーザーは何もクリックすることができず、UIは応答しません。私はこの問題を調査し、UIがプロトコル層での処理に忙しくて応答しないことが分かった。ここで

は私の問題です... uは私に

  1. 私は2 button..startを持っていると停止します...いくつかの解決策を与えることができます
  2. 私は、スタートボタンをクリックし
  3. ... Processorという名前の関数で大規模なプロセスが開始されます(50秒間続く大きな整数のforループ)。
  4. 処理時に、プロセッサはいくつかのウィンドウを作成し、5〜10秒待ってそれらを破棄することを示します。またはユーザーがクリックすると、ウィンドウ上に表示されます
  5. そして、停止ボタンをクリックしたときに停止ボタンをクリックできるようになるまで、そのプロセスは停止する必要があります。

バックグラウンドワーカー、ディスパッチャー、別スレッドを使って試しました。運がない。私は何かが足りないと思う。なぜなら、私はウィンドウを表示しているいくつかの結果を待っているからです。ウィンドウは間違いなくハングしてしまいます。もし私が別のスレッドでそれらを分ければ、それはお互いに通信しません。私にいくつかの提案をしてください

+1

'Dispatcher'は、CPUが非常に集中している場合でもUIをロックすることができますが、' BackgroundWorker'はうまく動作するはずです。 BackgroundWorkerで試したコードを表示できますか? – Rachel

答えて

0

Dispatcherは確かに解決策です。 Dispatcher Priorityを設定する必要があります。関連するコードを共有すると、いくつかの問題が明らかになることもあります。

+0

Dispatcherは引き続きメインのUIスレッドを使用し、CPUを集中的に使用している間にロックされる可能性があります。 – Rachel

+0

@レイチェル - だから私はスレッドの優先順位をどのスレッドに優先順位(* UI vsワーカー*)を割り当てるべきかに割り当てるべきだと提案したのです。 – SliverNinja

+1

@SilverNinja別のDispatcherPriorityを使用していてもUIをロックアップしています。私が諦めてバックグラウンドスレッドを使用する前に、可能な限り低い優先順位( 'SystemIdle')でテストしました。これは、CPUの集中的な操作であって、応答を待っていたデータベース呼び出しのようなものではありませんでした。 – Rachel

0

BackgroundWorkerは、必要な処理を行う必要があります。 WorkerSupportsCancellationとWorkerReportsProgressをtrueに設定します。

複数のウィンドウがポップアップすることはお勧めしません。 1つのウィンドウをポップアップしてステータスを表示します。 DoWorkのループで、BackgroundWorker.ReportProgressを呼び出します。次に、ProgressChangedイベントハンドラで、ウィンドウのステータスを更新します。

Stopを実装するには DoWorkメソッドでは、ループ内のBackgroundWorkerのCancellationPendingプロパティを確認する必要があります。それが本当であれば、その方法を終了する必要があります。停止ボタンをクリックして、BackgroundWorker.CancelAsync()を呼び出します。

+0

はい、動作します。しかし、私は、関数reportProgress内のwpfウィンドウの新しいインスタンスを作成しようとした...それは常にInvalidOperationの例外を示しています... "多くのUIコンポーネントがこれを必要とするため、呼び出しスレッドはSTAでなければなりません。私はウインドウのインスタンスを作成して、backgroundworkerプロセス内に表示できるように何かを提案することができます。ユーザーがキャンセルボタンをクリックすると、私はこれを破棄します。 –

+0

これで、バックグラウンドワーカーでプロセスを実行でき、このプロセスの実行時にtextBoxを更新できます。しかし、主な問題は、私はそのbackgroundworkerで別のwpfウィンドウの新しいインスタンスを作成することはできません。私はstackoverflowを検索し、それが可能ではないことがわかった(!)。 back..workerは、新しいウィンドウの作成時にSTAスレッドが必要なMTAスレッドを使用します。何らかの方法を提案してください –

+0

ここに詳細な記事があります。http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx DoWorkイベントでUIを変更しないでくださいハンドラ。代わりに、ProgressChangedまたはRunWorkerCompletedでUIを更新します。 – dmo

関連する問題