Getting a return value from a Task with C#

Sometimes you want to get a return value from a Task as opposed to letting it run in the background and forgetting about it. You’ll need to specify the return type as a type parameter to the Task object: a Task of T.

.NET 4.0

Without specifying an input parameter:

Task<int> task = new Task<int>(() => 
{
    int total = 0;
    for (int i = 0; i < 500; i++)
    {
        total += i;
    }
    return total;
});

task.Start();
int result = Convert.ToInt32(task.Result);

We count to 500 and return the sum. The return value of the Task can be retrieved using the Result property which can be converted to the desired type.

You can provide an input parameter as well:

Task<int> task = new Task<int>(obj => 
{
    int total = 0;
    int max = (int)obj;
    for (int i = 0; i < max; i++)
    {
        total += i;
    }
    return total;
}, 300);

task.Start();
int result = Convert.ToInt32(task.Result);

We specify that we want to count to 300.

.NET 4.5

The recommended way in .NET 4.5 is to use Task.FromResult, Task.Run or Task.Factory.StartNew:

FromResult:

public async Task DoWork()
{
       int res = await Task.FromResult<int>(GetSum(4, 5));	
}

private int GetSum(int a, int b)
{
	return a + b;
}

Please check out Stefan’s comments on the usage of FromResult in the comments section below the post.

Task.Run:

public async Task DoWork()
{
	Func<int> function = new Func<int>(() => GetSum(4, 5));
	int res = await Task.Run<int>(function);
}

private int GetSum(int a, int b)
{
	return a + b;
}

Task.Factory.StartNew:

public async Task DoWork()
{
	Func<int> function = new Func<int>(() => GetSum(4, 5));
	int res = await Task.Factory.StartNew<int>(function);			
}

private int GetSum(int a, int b)
{
	return a + b;
}

View the list of posts on the Task Parallel Library here.

Unknown's avatarAbout Andras Nemes
I'm a .NET/Java developer living and working in Stockholm, Sweden.

15 Responses to Getting a return value from a Task with C#

  1. Dmitry's avatar Dmitry says:

    Hi Andras,
    I have one question – which way is the best?

    • Andras Nemes's avatar Andras Nemes says:

      Hi Dmitry,
      it is recommended to avoid the Task constructor, i.e. Task t = new Task; t.Start;. If you can run your project on .NET4.5 then you can take the FromResult approach, otherwise any of the static approaches are fine: Task.Factory.Start, Task.Run, Task.FromResult

      //Andras

  2. TheMachine's avatar QuantumCD says:

    On a tangent, are tasks the “preferred” way of multithreading in C#?

  3. Stefan Ossendorf's avatar Stefan Ossendorf says:

    Hi Andras,
    nice article! But there is one flaw.
    Task.FromResult() is NOT async! It’s just a wrapper to get a Task with Status “RanToCompletion”.
    Your calling Thread will block until your operation is completed.

    Another way to get a (running) Task is the TaskCompletionSource (see: http://msdn.microsoft.com/de-de/library/dd449174%28v=vs.110%29.aspx)
    With a TaskCompletionSource you have more control over the tasks state Exception,Finished,Cancelled.

  4. Jaymark's avatar Jaymark says:

    I used the first method, it works, but my UI still freezes. Am I missing something?

    • Andras Nemes's avatar Andras Nemes says:

      Do you mean that the UI freezes for the duration of executing the task? When working with tasks in a UI application you have to make your asynchronous methods awaitable with the await and async keywords. Do you know what I mean? //Andras

  5. Pingback: How To Get A Return Value From A Thread C# | Technology Loves

  6. getting System.Threading.THreadiing.GetResultCore() @ task.Result line;

  7. lindexi's avatar lindexi says:

    You can use ValueTask

  8. Laball Lee's avatar Laball Lee says:

    Good.

Leave a comment

Elliot Balynn's Blog

A directory of wonderful thoughts

Software Engineering

Web development

Disparate Opinions

Various tidbits

chsakell's Blog

WEB APPLICATION DEVELOPMENT TUTORIALS WITH OPEN-SOURCE PROJECTS

Once Upon a Camayoc

ARCHIVED: Bite-size insight on Cyber Security for the not too technical.