0

WPF アプリケーションでは、ビュー モデルのコマンドにバインドされたボタンがあります。このコマンドは、タスクを起動してデータベースから情報を取得し、いくつかのプロパティを更新します。

//list in vm to be bound to..
List<DataModel.Item> BoundList;
//new command () =>
{
    var t = Task.Factory.StartNew<IEnumerable<DataModel.Item>>( () =>
       return datasvc.GetItems();
    );
    t.ContinueWith( t2 => {
       BoundList = t.Result;
    }, TaskScheduler.FromCurrentSychronizationContext);
}

t.Resultフラグを使用すると、プロジェクトはビルドエラーを報告しますが、FromCurrentSynchronizationContextフラグが存在しない場合はビルドエラーはありません。問題は、応答しない UI が表示されることです。

私は間違って何をしていますか?

4

1 に答える 1

3

これはフラグではなく、静的メソッドです。また、t2 はタスクの結果であるため、元のタスクを別の変数として保存する必要はありません。

Task.Factory.StartNew(datasvc.GetItems)
    .ContinueWith( 
        t => 
        {
            BoundList = t.Result;
        }, TaskScheduler.FromCurrentSychronizationContext());

オブジェクトが UI スレッドで実行されているTask(つまりフリーズしている) 場合は、スレッド プールで既に多数のスレッドを実行していることが原因である可能性があります。デフォルトでは、スレッドがすべて使用されていない限り、Taska はスレッドで実行されます。ThreadPool

ただし、実行時間の長い操作であることを .NET に通知することはできます。通常は、UI のフリーズを防ぐことができる追加のスレッドが生成されます。

MSDNから:

TaskCreationOptions.LongRunning
タスクが、きめの細かいシステムよりも少数の大きなコンポーネントを含む、長時間実行される粗い操作になることを指定します。オーバーサブスクリプションが保証される可能性があるというヒントを TaskScheduler に提供します。オーバーサブスクリプションを使用すると、使用可能なハードウェア スレッド数よりも多くのスレッドを作成できます。

したがって、タスクの作成を次のように変更します。

Task.Factory.StartNew(datasvc.GetItems, TaskCreationOptions.LongRunning)
于 2013-07-08T17:07:30.283 に答える