0

In the following code, pressing button1 performs a lengthy calculation and shows the result in the window title bar. It works, but can I access the task's Status to check if the task ran successfully (TaskStatus.RanToCompletion)?

async private void button1_Click(object sender, EventArgs e)
{
    Text = "Working";
    int val = await LongTask();
    Text = "Done: " + val;
}

async Task<int> LongTask()
{
    return await Task.Run( () => LongFunction());
}

int LongFunction()
{
    Thread.Sleep(5000);
    return 1;
}

2 Answers 2

4

You can check the status by using the property on the property on the Task. But one of the great things about async \ await is that you don't need to do this. When you await, any exceptions that are thrown from the inner delegate inside Task.Run(...) bubble up and you can catch them as if it were synchronous code.

For example:

Text = "Working";
try {
    int val = await LongTask();
    Text = "Done: " + val;
}
catch (Exception ex)
{
  // Something went wrong
}
Sign up to request clarification or add additional context in comments.

Comments

2

If you really wanted to you could

var task = SomeMethodAsync();
await task;
var status = task.Status;

But that's pointless because if you're at the line after the await then task has completed, so you just know that's the answer already.

You could catch an exception and then look at the status to distinguish cancellation from faulting, but you can tell that from the exception too, so again it's pointless.

The opposite can be sometimes useful. Say we have:

public async Task XAsync()
{
  await YAsync();
  await ZAsync();
}

Now let's say that YAsync has a high chance of returning synchronously. Then we could do:

public Task XAsync()
{
  Task task = YAsync();
  if (task.Status == TaskStatus.RanToCompletion)
    return ZAsync();
  // Do the awaiting
  return XAsync(task);
}

private async Task XAsync(Task task)
{
  await task;
  await ZAsync();
}

Avoiding the extra allocation and state-machine set-up in this way is only worth it in frequently hit methods, and again only worth it if the odds of the first task repeating synchronously is very high. It also leads to slightly more confusing traces if something goes wrong, but it can have a significant impact.

So testing the status before await has that use. Testing after await tells you something you already know.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.