2011-08-10 18 views
6

私はWPFの初心者です。私のアプリケーションでは、一連の初期化ステップを実行する必要があります。これらのステップは、UIが応答しなくなるまでに10〜15秒かかります。WPFでバックグラウンドワーカーを使用する代替手段はありますか?

私はバックグラウンドワーカーを昨日使用していましたが、実際にはフリーズしていましたが、ウィンドウが更新されませんでした。わかりませんが、このコントロールはWindowsフォームのみのため動作しませんでした。

UPDATE:

ない面倒ならば、あなたは私の代替を使用する例を投稿することができますか?私の場合、プログラムは、データベースからいくつかの値を取得します。

+0

バックグラウンド作業者の場合、ReportProgress()を実装しましたか? http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.reportprogress.aspx –

+0

@Jon Raynor実際には –

+1

@ Oscar:BackgroundWorker:DoWorkはUIを応答不能にしません。おそらく、BackgroundworkerのAsyncCompletedイベントでUIの更新を行っている可能性があります。 backgroundWorkerをデータベースから取得するためだけに使用する場合は、UIをフリーズせずに動作するはずです。 – CharithJ

答えて

6

Dispatcher。 Dispatcherは、特定のスレッドの作業項目の優先順位付きキューを維持します。これは、あなたのUIを更新するのに役立ちます。 UIに関連した初期化がたくさんある場合でも、これはあなたに多くの手助けをすることはできません。

Dispatcherは実際にはBackgroundWorkerの代替手段ではありません。ベストプラクティスは、要件に応じてより適切なものを選択することです。たとえば、キュ​​ーに入れずに何かを実行したい場合、BackgroundWorkerがソリューションです。一方、キューイングが問題ではない場合、Dispatcherは代替手段です。例えば、Dispatcherはスペルチェッカーと構文強調表示機能で使用しています。

WPF Thread Model

すべてのWPFアプリケーションでは、2つの重要なスレッド、 レンダリング用とユーザーインターフェースを管理するための1から始めます。レンダリング スレッドはバックグラウンドで実行される隠されたスレッドなので、通常扱う スレッドのみがUIスレッドです。 WPFでは、ほとんどのオブジェクトがUIスレッドに結び付けられることを が要求します。これは スレッドアフィニティとして知られています。つまり、作成されたスレッド でのみWPFオブジェクトを使用できます。それを他のスレッドで使用すると、 実行時例外がスローされます。 WPFスレッドモデル は、Win32®ベースのAPIと相互運用性が高いことに注意してください。これは、WPFが ホストかHWNDベースのAPI(Windowsフォーム、VisualBasic®、 MFC、またはWin32)によってホストされることを意味します。

スレッドアフィニティは、WPFアプリケーションの優先順位付きメッセージループであるDispatcher クラスによって処理されます。通常、 WPFプロジェクトには、すべてのユーザーインターフェイスの作業がチャネルされる単一のDispatcherオブジェクト(したがって、単一の UIスレッド)があります。

注:

ディスパッチャと他のスレッドの方法 間の主な違いは、ディスパッチャが実際にマルチスレッドではないということです。ディスパッチャ は、正しく機能するには1つのスレッドを必要とするコントロールを制御します。 DispatcherのBeginInvokeメソッドは、遅くとも の実行のためにイベントをキューに入れます(優先順位などによるが、同じスレッド上にある)。

詳細については、thisスレッドを参照してください。

0

スレッドプールを使用してアイテムをキューに入れ、そのようなタスクを実行することもできますが、タスクが完了したらUIを更新する必要がある場合は、データをUIスレッドに戻してマーシャリングする必要があります。

0

非同期デリゲートを使用できます。

http://msdn.microsoft.com/en-us/library/ms228963.aspx

あなたが任意のUI関連の更新を行っている場合は念を使用します。

ここ
Dispatcher.CheckAccess() 

簡単な例:ここから撮影

private void HandleUIButtons() 
{  
    if (!btnSplit.Dispatcher.CheckAccess()) 
    {   
     //if here - we are on a different non-UI thread   
     btnSplit.Dispatcher.BeginInvoke(new Action(HandleUIButtons));  
    }  
    else   
    { 
     btnSplit.IsEnabled = true; //this is ultimately run on the UI-thread 
    } 
} 

http://blog.clauskonrad.net/2009/03/wpf-invokerequired-dispatchercheckacces.html

関連する問題