1

I want to have an async method in my call that would be called by my library consumers with an await. But the internal working of my method, while I need it to run on a separate thread, does not call any other await on it's own.

I just do the work the method is supposed to do and return the type. And the compiler warns me that this method will not run in an async way.

public async Task<MyResultObject> DoSomeWork()
{
     MyResultObject result = new MyResultObject();
     // Some work to be done here

     return result;
}

On the other hand, if I write a method that starts a new task using TaskFactory like this:

public Task<MyResultObject> DoSomeWork()
{
     return Task<MyResultObject>.Factory.StartNew(() =>
     {
         MyResultObject result = new MyResultObject();
         // Some work to be done here

         return result;
     });
}

Then I cannot call it using the await keyword like this await DoSomeWork().

How do I write an async (must be async and not task with result or wait) without using some await call inside?

10
  • 5
    while I need it to run on a separate thread - if you are not making that happen yourself inside the method, e.g. with Task.Run(), then that is not going to happen when your method is called with await either, because async is not about threads. Commented Jan 3, 2019 at 12:45
  • 8
    aync/await is an implementation detail of the method. The only thing that matters is it returns a Task. If you need to return a task but have no async source just use Task.FromResult Commented Jan 3, 2019 at 12:47
  • 2
    Your code will be synchronous and will block. If you don't want that to happen, use Task.Run. Commented Jan 3, 2019 at 12:51
  • 4
    If your method is essentially synchronous, leave it as a synchronous method and leave it up to your callers to decide whether to call it directly or to use e.g. Task.Run. As others have said (and as the compiler warnings say if you try to do this), async by itself doesn't do anything from the callers perspective. Commented Jan 3, 2019 at 12:53
  • 2
    Async is about scaling, not multi-processing. Async methods generate code to give up their thread while they wait for some IO bound task (so the thread can be used to process other requests). Then, when the IO is completed, it resumes. Commented Jan 3, 2019 at 13:04

1 Answer 1

3

You can do this

public Task<MyResultObject> DoSomeWork()
{
     MyResultObject result = new MyResultObject();
     // Some work to be done here

     return Task.FromResult(result);
}

which is exactly the same as

public async Task<MyResultObject> DoSomeWork()
{
     MyResultObject result = new MyResultObject();
     // Some work to be done here

     return result;
}

Only this version gives a warning and has slightly more overhead.

But neither will run on another thread. The only benefit is that they have an awaitable interface.

To do it in parallel, your code is Ok but Task.Run is preferred over StartNew():

public Task<MyResultObject> DoSomeWork()
{
     return Task.Run(() =>
     {
         MyResultObject result = new MyResultObject();
         // Some work to be done here

         return result;
     });
}

And in all these cases you can definitely await DoSomeWork()

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

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.