async\await и иже с ними

59 views
Skip to first unread message

Денис Тарасов

unread,
Jul 7, 2016, 3:29:09 PM7/7/16
to dotne...@googlegroups.com
Всем привет! 

Заметил, что в некоторых моментах, когда нужно запустить на пуле продолжение выполнения метода, то достаточно удобно использовать Task.Yeld:

using System;
    using System.Threading;
    using System.Threading.Tasks;

    internal class Program
    {
        private static void Main(string[] args)
        {
            var test = new Test();

            test.Run1().GetAwaiter().GetResult();
            Console.WriteLine(new string('-', 30));

            test.Run1().GetAwaiter().GetResult();
            Console.WriteLine(new string('-', 30));

            Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
            Console.ReadLine();
        }
    }

    public class Test
    {
        public async Task Run2()
        {
            Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
            await Task.Yield();
            Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
        }

        public async Task Run1()
        {
            Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
            await Task.Factory.StartNew(() => Console.WriteLine(Thread.CurrentThread.ManagedThreadId));
        }
    }

Как считаете, имеет право на жизнь и если да, то  почему такой подход не распространен?

Артём Мурадов

unread,
Jul 9, 2016, 12:42:43 AM7/9/16
to dotnetconf
Ну, по мне, для того, кто будет потом этот код читать, не очень то и очевидно, как это будет работать. 
Мало того, эта штука использует текущий контекст синхронизации (если он есть), а значит, например, в WPF продолжение запустится в UI потоке, а это ай ай ай. То есть, штука эта, конечно, асинхронная, но вот насчет запуска кода в пуле потоков - это очень зависит от текущего контекста. Как пример:

internal class Program
{
[STAThread]
private static async void Main(string[] args)
{
Application app = new Application();
app.Run(new MyForm());
}

class MyForm : Window
{
public MyForm()
{
this.Loaded+=wLoaded;
}

private async void wLoaded(object sender, EventArgs e)
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
await Task.Yield();
Thread.Sleep(5000);
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
}
}
}

выдаст одинаковый ID потока.

четверг, 7 июля 2016 г., 21:29:09 UTC+2 пользователь denis.tarasov.netwrix написал:
Reply all
Reply to author
Forward
0 new messages