5

私のアプリケーションには複数のタブがあり、Entity Framework 5 を使用してデータベースのデータを表示しています。

タブを切り替えると、タスクを介してデータの自動ロードを開始します。これは、GUI が応答しなくなることを望まないためです (このタスクには約 5 ~ 10 秒かかります)。

public async void LoadData()
{
    [...]

    await Task.Run(
        () =>
            {
                Measurements = DataContext.Measurements
                                  .Where(m => m.MeasureDate = DateTime.Today)
                                  .ToList();
            });

    [...]
}

ただし、タスクの実行中にユーザーは別のタブに変更できます。その場合、EF クエリやタスクをキャンセルしたいと思います。

これを達成するための最良の方法は何ですか?

4

2 に答える 2

8

EF5 では、 を受け入れないため、クエリをキャンセルする方法はありませんCancellationToken。詳細については、こちらをご覧ください:エンティティ フレームワークは長時間実行クエリをキャンセルします。

ただし、EF6 ではサポートされています。

すべてのメソッドの非同期バージョンがあります。そのToList()代わりにToListAsync()、長時間実行されるクエリの可能性があり、CancellationToken.

于 2013-08-05T13:37:24.277 に答える
0
// ***Declare a System.Threading.CancellationTokenSource.
CancellationTokenSource cts;
public async void LoadData()
{
   // ***Instantiate the CancellationTokenSource.
    cts = new CancellationTokenSource();
    await Task.Run(
        () =>
            {
                Measurements = DataContext.Measurements
                                  .Where(m => m.MeasureDate = DateTime.Today)
                                  .ToList();
            }, cts);

}

    //I dont know what front end you using but in WPF for example on the tab event
    <TabControl SelectionChanged="OnSelectionChanged" ... />

private void OnSelectionChanged(Object sender, SelectionChangedEventArgs args)
{
    TabItem item = sender as TabItem; //The sender is a type of TabItem...

    if (item != null)
    {
         if (cts != null)
         {
            //This cancels the current long Running task.
            cts.Cancel();

            //call for next tab with filter LoadData(filter);
         }
    }
}

私の個人的な見解です。これを行う最善の方法は、可能であれば、タブのすべてのデータを事前にロードすることです。次に、ビューをレンダリングします。したがって、タブ間をクリックすると、データはすでに読み込まれています。さらに、データベースを呼び出すコストは一度しか影響しません。タブをクリックするたびにデータベースに往復する代わりに。

于 2013-08-05T14:07:49.873 に答える