6

I would like to write the following:

public string GetSomeValue()
{
    //directly return the value of the Method 'DoSomeHeavyWork'...
    var t = DoSomeHeavyWork();
    return t.Result;
}

public Task<string> DoSomeHeavyWork()
{
    return Task.Run(() => {
        // do some long working progress and return a string
        return "Hello World!";
    });
}

As you can see to return the result from the DoSomeHeavyWork() I have used the Task.Result property, which works okay, but according to researches this will block the Thread.

I would like to use the async/await pattern for this but cant seem to find how to do this. If I did the same with async/await with my current knowledge I will always end up with this:

public async Task<string> GetSomeValue()
{
    //directly return the value of the Method 'DoSomeHeavyWork'...
    var t = DoSomeHeavyWork();
    return await t;
}

public Task<string> DoSomeHeavyWork()
{
    return Task.Run(() => {
        // do some long working progress and return a string
        return "Hello World!";
    });
}

This solution doesnt quite fit my needs because I want to return ONLY the string and not a Task<string>, how can this be achieved with async/await?

1
  • Why can't you return Task<string> because when you await it it returns a string. Isn't that what you want? Commented Apr 22, 2016 at 4:21

1 Answer 1

11

You can't.

The entire point of async is to run code asynchronously. So the code returns a promise of a future string value, represented in .NET as Task<string>.

Think about it this way: if your code calls public string GetSomeValue(), then by the time the method returns, you already have a string. This is synchronous, by definition.

In your example, you have "heavy" work which I interpret to mean "CPU-bound". In that case, just do the work synchronously:

public string DoSomeHeavyWork()
{
  // do some long working progress and return a string
  return "Hello World!";
}

In general, APIs should not "lie"; if they are synchronous, then they should have a synchronous (non-Task-returning) signature.

Edit: As per your comment, the "heavy" work is a WCF call, which is I/O-bound, not CPU-bound.

In that case, the work is naturally asynchronous. Use asynchronous WCF methods (not Task.Run), and allow the asynchrony to grow through your codebase:

public async Task<string> GetSomeValueAsync()
{
  //directly return the value of the Method 'DoSomeHeavyWork'...
  var t = DoSomeHeavyWorkAsync();
  return await t;
}

public async Task<string> DoSomeHeavyWorkAsync()
{
  // Call asynchronous WCF client.
  await ...;
  return "Hello World!";
}
Sign up to request clarification or add additional context in comments.

7 Comments

How would you solve my problem, with the Task.Result property or do you know of anything better? (Would be happy about code snippets if you know a better alternative)
In my real live example I am calling a WCF request to a client, and wanted to have a method thats running async to not block the client while server is calling the method (both Server/Client are WPF) should I than return the Task object instead of the resolved string/object?
I've edited my answer with my preferred solution: just do the work directly. And I've edited it again since the "heavy" work is a WCF request.
So its no issue if the WCF client implements the following interface: [OperationContract()] Task<string> GetAccountValue(string accNr, string propertyName); instead of a simple string/object?
Right; anything Task-returning is asynchronous, and if you consume it asynchronously (via await), it all works.
|

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.