1

静的メソッドをタスクとして呼び出す非同期メソッドOnValueChangeがあり、メソッドは Iprogress インターフェイスの助けを借りて GUI を更新し、メソッドは画像を返します。

  public async void OnValueChange(object sender, EventArgs e) 
  {
      var progress = new Progress<int>(i => ProgresBar.Value = i);

      Image im = await Task.Factory.StartNew(() => MyStaticClass.MyStaticFunction(progress),
      TaskCreationOptions.LongRunning);

      Picture = im;
  }

場合によっては、OnValueChange 関数を短時間で頻繁に呼び出していますが、一度に 1 つのタスクだけを実行したいです。

特定のメソッドを持つタスクが既に実行されているかどうかを確認する最も効率的な方法は何ですか?

4

1 に答える 1

3

避けるべきasync voidです。余談ですが、私のブログで、あなたの使い方StartNewは危険だと説明しています(代わりに使用する必要がありますTask.Run)。

これらのガイドラインの両方を例に適用すると、コードは次のようになります。

public async Task OnValueChangeAsync() 
{
  var progress = new Progress<int>(i => ProgresBar.Value = i);
  Image im = await Task.Run(() => MyStaticClass.MyStaticFunction(progress));
  Picture = im;
}

public async void OnValueChange(object sender, EventArgs e) 
{
  await OnValueChangeAsync();
}

この時点で、メソッドが既に実行されているかどうかを検出する方法がより明確になります (そのメソッドは実際にTasknow を返すため)。1つの実装は次のとおりです。

private async Task OnValueChangeImplAsync()
{
  var progress = new Progress<int>(i => ProgresBar.Value = i);
  Image im = await Task.Run(() => MyStaticClass.MyStaticFunction(progress));
  Picture = im;
  _onValueChangeTask = null;
}

private Task _onValueChangeTask;
public Task OnValueChangeAsync()
{
  if (_onValueChangeTask != null)
    return _onValueChangeTask;
  _onValueChangeTask = OnValueChangeImplAsync();
  return _onValueChangeTask;
}

public async void OnValueChange(object sender, EventArgs e) 
{
  await OnValueChangeAsync();
}
于 2013-10-03T23:59:34.547 に答える