D
D
DarkByte20152016-05-06 08:23:42
C++ / C#
DarkByte2015, 2016-05-06 08:23:42

How to make async without await?

What if the method should be asynchronous (async Task), but there is absolutely nowhere to insert await in it? And I don't want to spawn Task.Run threads. The only thing that comes to mind is to do await Task.Delay(1). Those. no one will notice one millisecond, but the method will already be asynchronous. But this IMHO is a very clumsy solution. Are there any other options?

Answer the question

In order to leave comments, you need to log in

3 answer(s)
I
Iron Bug, 2016-05-06
@DarkByte2015

Add
await Task.Yield();
stackoverflow.com/questions/22645024/when-would-i-...

N
Nikolay Maev, 2016-05-06
@Trixon

You call await on a method marked async, let's call it MethodAsync.
In the MethodAsync method, at the point where another asynchronous method is called along with await, the compiler splits the MethodAsync method into two parts. Before await and after await.
Everything before the await is executed in the context of the primary thread.
The operation marked await (in the MethodAsync method) + everything after it is executed in the context of a secondary thread.
By calling await Task.Delay, you are still borrowing a secondary thread from the pool. We can say that this is the same as calling await Task.Run, placing there the part of the method that would be after await Task.Delay.
Here is the code, try it:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        static async Task MethodDelayAsync()
        {
            Console.WriteLine("1. MethodDelayAsync: before await thread id: {0}", Thread.CurrentThread.ManagedThreadId);

            await Task.Delay(1000);

            Console.WriteLine("2. MethodDelayAsync: after await thread id: {0}", Thread.CurrentThread.ManagedThreadId);
        }
        
        static async Task MethodTaskRunAsync()
        {
            Console.WriteLine("1. MethodTaskRunAsync: before await thread id: {0}", Thread.CurrentThread.ManagedThreadId);

            await Task.Run(() =>
            {
                Console.WriteLine("Asynchronous operation in MethodTaskRunAsync in thread id: {0}",
                    Thread.CurrentThread.ManagedThreadId);
            });

            Console.WriteLine("2. MethodTaskRunAsync: after await thread id: {0}", Thread.CurrentThread.ManagedThreadId);
        }

        static void Main(string[] args)
        {
            Console.WriteLine("Start Main in thread id: {0}", Thread.CurrentThread.ManagedThreadId);

            //MethodDelayAsync();
            MethodTaskRunAsync();

            Console.WriteLine("End Main in thread id: {0}", Thread.CurrentThread.ManagedThreadId);
            
            Console.Read();
        }
    }
}

Uncommenting MethodTaskRunAsync:
Start Main in thread id: 1
1. MethodTaskRunAsync: before await thread id: 1
Asynchronous operation in MethodTaskRunAsync in thread id: 3 -- secondary thread from the pool.
End Main in thread id: 1
2. MethodTaskRunAsync: after await thread id: 3 -- secondary thread from the pool.
Uncommenting MethodDelayAsync:
Start Main in thread id: 1
1. MethodDelayAsync: before await thread id: 1
End Main in thread id: 1
2. MethodDelayAsync: after await thread id: 4 -- secondary thread from the pool.
And this means that everything happens exactly as I said above.

Z
zzzzzzerg, 2016-05-06
@zzzzzzerg

Task.Run add a task to the queue that runs on the thread pool, i.e. you won't have additional thread creation.
Also, I didn't find Task.Join in the documentation, so I don't understand what you mean.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question