0

私はこのデリゲートを持っています:

private delegate void NoArgDelegate(BitmapImage image);

デリゲートをインスタンス化し、次のように Dispatcher.Invoke で実行します。

var fetcher =  new NoArgDelegate(InstantiateForm);
Dispatcher.Invoke(fetcher, DispatcherPriority.Normal, imageToPassIn);

メソッドのスコープ外にプライベート フィールドがありますが、ViewModel のスコープ内、InstantiateForm 内でオブジェクトをインスタンス化します。

private OmrForm _ormForm;

private void InstantiateForm(BitmapImage image)
{
    _ormForm = new OmrForm(image);
}

これはすべて、WPF フォームのボタンのクリック イベントで実行される ViewModel 内のメソッドで発生しています。

コンストラクターで、渡した画像の種類を特定し、座標を適切に設定するためにいくつかの作業を行います。これは約 2 秒です。この間、UI を応答させたいのですが、そうではありません。私も BeginInvoke を使用してみましたが、役に立ちませんでした。

ここで何が起こっているのですか? メソッドが非同期で実行されないのはなぜですか?

4

3 に答える 3

3

コントロールの Dispatcher は UI スレッドで動作するように設定されているため、Window または UserControl 内で呼び出すDispatcher.Invokeと、そのコードが UI スレッドで実行されます。

あなたが望むのは、バックグラウンドスレッドを開始することです。Taskこれは、クラスを使用して実現できます。

Task.Factory.StartNew(() => InstantiateForm(imageToPassIn));
于 2013-01-16T14:35:44.047 に答える
1

Dispatcher.Invokeアクションをキューに入れ、UI スレッドで実行します。長い計算を実行したい場合は、おそらくワーカー スレッドで実行して、UI スレッドが他の処理を実行できるようにする必要があります。たとえば、 を試すことができThreadPool.QueueUserWorkItemます。

于 2013-01-16T14:35:43.907 に答える
0

問題は、新しいものを構築するにはWindowまだディスパッチャーが作業を行う必要があることです。そのため、コンストラクターのWindow実行に時間がかかる場合、ディスパッチャーは以前に呼び出したにもかかわらず、そのコンストラクターが終了するのを待ってスタックしInvokeます。

やりたいことは、コンストラクターを非常に高速にしてから、画像を設定するために使用できるプロパティを作成し、そのプロパティがすべての時間のかかる作業を非同期で実行するようにして、UI スレッドが拘束されないようにすることです。

スレッド化を使用してメソッドを呼び出すことを提案する人もいますがWindow、別のスレッドで新しいを作成することはお勧めできません。また、別の意味もあります。

于 2013-01-16T14:38:32.810 に答える