3

I just had following piece of code, which did not compile:

public Task<int> Handle
{
    var result = <do_something_returning_an_int>();
    ...
    return result;
}

This gives compiler error `cannot implicitly convert type 'int' to 'System.Threading.Thread.Task'.

When I change this into:

async Task<int> Handle
{
    var result = <do_something_returning_an_int>();
    ...
    return result;
}

... no compiler error.

I know that async means that the task does not need to wait for the answer to arrive, but what does this have to do with typecasting?

5
  • 6
    Is the method using an await anywhere? If the method isn't async then it won't automatically produce a Task<>, the code would need to return that type explicitly. And an int is not a Task<int>. (The difference between those types has exactly nothing to do with the public access modifier.) Commented Nov 23, 2022 at 16:04
  • 2
    I would suggest to make both methods public, to eliminate any confusion regarding this difference. Commented Nov 23, 2022 at 16:06
  • 1
    async actually means: this method has something that can be awaited. Otherwise there's no need to use async. Commented Nov 23, 2022 at 16:13
  • This is a part of the C# Language Specification. Read it, or read Async return types (C#) § Task<TResult> return type. Commented Nov 23, 2022 at 16:38
  • @JeppeStigNielsen: your comment seems to be the closest to the solution. Can you put it as an answer? I'll accept it. Commented Nov 24, 2022 at 7:29

3 Answers 3

5

If you're not awaiting anything in your asynchronous method you omit the async keyword and return a Task instead of the result directly.

public Task<int> Handle
{
    var result = <do_something_returning_an_int>();
    ...
    return Task.FromResult(result);
}

As far as I can tell, doing that only makes sense if other code strictly expects a Task from your method.

This has of course nothing to do with access modifiers, you can combine async with public or any other access modifier.

I'd also recommend taking a look at the documentation

Sign up to request clarification or add additional context in comments.

Comments

2

(By request, promoted from a comment.)

This is by design of the async logic in the C# Language Specification. See the section Async Functions.

You can also read the programming guide, Async return types (C#) § Task<TResult>.

The point is that a method without the async keyword, like

public Task<int> HandleAsync()
{
    ...
    Task<int> result = ...;
    ...
    return result;
}

must return what it says it returns, just as with all other types. In this case, you could create a Task<> that can be awaited, in your own manual way, like:

Task<int> result = Task.Run(GetLastDigitOfSmallestTwinPrimeWithMoreThan1000000Digits);

The caller can await the task you return, even if your method is written like above.

But if you use the async keyword, and if your return type is, say, Task<int>, then you must return a plain int, and the C# compiler will write the needed logic for you.

Usually, you would use await somewhere in the body (otherwise, why async). So something like:

public async Task<int> HandleAsync()
{
    ...
    int result = await GetLastDigitOfSmallestTwinPrimeWithMoreThan1000000DigitsAsync();
    ...
    return result;
}

Related question here: Why is it not necessary to return a Task when the signature is public async Task MethodName?

1 Comment

Another related thread: async await return Task.
1

try using task result and then iterate the results

Task<int> Handle
{
    return Task.Run(()=>
    {
       var result = <do_something_returning_an_int>();
       ...
       return result;
    }
}

List<Task<int>> tasks = new List<Task<int>>();
tasks.Add(Handle);
Task.WaitAll(tasks.ToArray());
for(int ctr = 0; ctr < tasks.Count; ctr++) {
                if (tasks[ctr].Status == TaskStatus.Faulted)
                    output.WriteLine(" Task fault occurred");
                else
                {
                    output.WriteLine("test sent {0}",
                                      tasks[ctr].Result);
                    Assert.True(true);
                }
            }

or

Task<int> Handle
{
   return Task.FromResult(do_something_returning_an_int);
}

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.