Martin877
Martin877

Reputation: 273

check if task with specific method is already running

I have async method OnValueChange where i call static method as a task, my method is updating gui with help of Iprogress intereface and my method is returning Image:

  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;
  }

In some cases i am calling OnValueChange function frequently in short period of time, but i want only one task running at time.

what is most efficient method to check if task with specific method is already running?

Upvotes: 1

Views: 2989

Answers (1)

Stephen Cleary
Stephen Cleary

Reputation: 457302

You should avoid async void. On a side note, I explain on my blog that the way you're using StartNew is dangerous (you should use Task.Run instead).

Applying both of these guidelines to your example, the code will look like this:

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();
}

At this point, it becomes more clear how to detect whether a method is already running (since that method actually returns a Task now). One implementation is as such:

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();
}

Upvotes: 3

Related Questions