Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Помогите понять async-await / 10 сообщений из 10, страница 1 из 1
21.09.2014, 15:17
    #38752925
Awaiter
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите понять async-await
Привет.

Изучаю async-await. Появилось пара вопросов:

1. Для чего нужен метод Task.Yield ?

Вот нагуглил код, зачем там нужен Task.Yeld ?

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
class Program
    {
        private static CancellationTokenSource CancellationTokenSource;

        static void Main(string[] args)
        {
            SelfCancellingAsync();
            SelfCancellingAsync();
            SelfCancellingAsync();

            Console.ReadLine();
        }

        private static async void SelfCancellingAsync()
        {
            Console.WriteLine("SelfCancellingAsync starting.");

            var cts = new CancellationTokenSource();
            var oldCts = Interlocked.Exchange(ref CancellationTokenSource, cts);

            if (oldCts != null)
            {
                oldCts.Cancel();
            }

            // Allow quick cancellation.
            await Task.Yield();

            if (cts.IsCancellationRequested)
            {
                return;
            }

            // Do the "meaty" work.
            Console.WriteLine("Performing intensive work.");

            var answer = await Task
                .Delay(TimeSpan.FromSeconds(1))
                .ContinueWith(_ => 42, TaskContinuationOptions.ExecuteSynchronously);

            if (cts.IsCancellationRequested)
            {
                return;
            }

            // Do something with the result.
            Console.WriteLine("SelfCancellingAsync completed. Answer: {0}.", answer);
        }
    }




2. Вот я написал простой код, который не работает. Почему ?


Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
    public partial class Form1 : Form
    {
        private Random _rnd = new Random();
        private SynchronizationContext _sync;

        public Form1()
        {
            InitializeComponent();

            _sync = SynchronizationContext.Current;
        }

        private async Task<string> GetRandomNumber(int I)
        {
            await Task.Delay(5000);
            return I.ToString() + ": " + _rnd.Next(100).ToString();
        }

        private async Task DoStuff()
        {
            await Task.Run(async () =>       << Компилятор дает подсказку на этот async, о том, что мало await'ов и код будет выполнятся синхронно. Но куда тут вставить await ??
            {                
                for (int i = 0; i < 10; i++)
                {
                    int tempI = i;
                    _sync.Send(async _ =>       << вызываю метод синхронизационного контекста, и помечаю лябду как асинхронную (иначе не вызвать await внутри). Все верно ?
                    {
                        string sss = await GetRandomNumber(tempI);
                        listBox1.Items.Add(sss);
                    }, null);
                }
            }
            );
        }

        private async void button1_Click(object sender, EventArgs e)
        {
            button1.Enabled = false;

            try
            {
                await DoStuff();
            }
            finally
            {
                button1.Enabled = true;
            }
        }
}



Почему-то код сразу падает в finally, не ожидая завершения задачи. Т.е. кнопка блокируется на долю секунды.
Как нужно переписать, чтобы было правильно ?
...
Рейтинг: 0 / 0
21.09.2014, 17:00
    #38752969
codearticles.ru
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите понять async-await
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
public partial class Form1 : Form
{
    private Random _rnd = new Random();

    public Form1()
    {
        InitializeComponent();
    }

    private async Task<string> GetRandomNumber(int i)
    {
        await Task.Delay(500);
        return string.Format("{0}:{1}", i, _rnd.Next(100));
    }

    private Task<string[]> DoStuff()
    {
        return Task.Run(async () =>
        {
            var list = new List<string>();

            for(int i = 0; i < 10; i++)
            {
                var s = await GetRandomNumber(i);
                list.Add(s);
            }

            return list.ToArray();
        });
    }

    private async void button1_Click(object sender, EventArgs e)
    {
        button1.Enabled = false;

        try
        {
            listBox1.Items.AddRange(await DoStuff());
        }
        finally
        {
            button1.Enabled = true;
        }
    }
}
...
Рейтинг: 0 / 0
21.09.2014, 17:20
    #38752979
Awaiter
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите понять async-await
codearticles.ru,

Спасибо )
Я понял. Асинхронные функции не должны делать какую-то работу извне? а только возвращать результат.
Хорошо, буду стараться писать так.
...
Рейтинг: 0 / 0
21.09.2014, 17:27
    #38752981
codearticles.ru
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите понять async-await
Awaitercodearticles.ru,

Спасибо )
Я понял. Асинхронные функции не должны делать какую-то работу извне? а только возвращать результат.
Хорошо, буду стараться писать так.
Ну почему же. Я понял твой намек, ты хочешь, чтобы на лету отображались добавленные элементы в ListBox. Тогда нужно немного переписать код. Как видишь, всё зависит от задачи. Живые UI пишутся на раз.

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
public partial class Form1 : Form
{
    private Random _rnd = new Random();

    public Form1()
    {
        InitializeComponent();
    }

    private string GetRandomNumber(int i)
    {
        return string.Format("{0}:{1}", i, _rnd.Next(100));
    }

    private async Task DoStuff(SynchronizationContext _sync, ListBox box)
    {
        await Task.Factory.StartNew((b) => 
        {
            for (int i = 0; i < 10; i++)
            {
                _sync.Send((a) =>
                {
                    (b as ListBox).Items.Add(a);
                }, GetRandomNumber(i));

                Thread.Sleep(1000);
            }
        }, box);
    }

    private async void button1_Click(object sender, EventArgs e)
    {
        button1.Enabled = false;

        try
        {
            await DoStuff(SynchronizationContext.Current, listBox1);
        }
        finally
        {
            button1.Enabled = true;
        }
    }
}
...
Рейтинг: 0 / 0
21.09.2014, 17:28
    #38752983
Awaiter
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите понять async-await
codearticles.ru,

Спасибо большое !!!
Тема очень интересная, и вот изучаю ее с нуля. Поэтому и хочется узнать все возможные стороны :) Чтобы уметь и так и так делать.
...
Рейтинг: 0 / 0
21.09.2014, 17:29
    #38752984
Awaiter
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите понять async-await
вообще, меня очень сильно смущает, что в асинхронных метода нету return :) Очень необычно )
...
Рейтинг: 0 / 0
21.09.2014, 17:37
    #38752991
codearticles.ru
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите понять async-await
Awaiter Поэтому и хочется узнать все возможные стороны :) Чтобы уметь и так и так делать.
Почитай вот этот pdf, всё предельно просто на примерах рассказывается http://codearticles.ru/articles/2491

Awaiterвообще, меня очень сильно смущает, что в асинхронных метода нету return :) Очень необычно )
Как это нету? :)

Код: c#
1.
2.
3.
4.
5.
public async Task<bool> Foo()
{
    await Task.Yield();
    return true;
}



Как-раз ответ на твой вопрос по поводу Task.Yield
...
Рейтинг: 0 / 0
21.09.2014, 17:41
    #38752994
codearticles.ru
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите понять async-await
Например, в WPF / Silverlight / Modern UI еще проще, там есть свой диспетчер. Можно прям в нем обращаться к контролам. Очень удобно.

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
private async Task DoStuff(ListBox box)
{
    await Task.Factory.StartNew((b) =>
    {
        for (int i = 0; i < 10; i++)
        {
            Dispatcher.InvokeAsync(() => 
            {
                listBox1.Items.Add(i);
            });

            Thread.Sleep(1000);
        }
    }, box);
}

private async void Button_Click(object sender, RoutedEventArgs e)
{
    button1.IsEnabled = false;
            
    try
    {
        await DoStuff(listBox1);
    }
    finally
    {
        button1.IsEnabled = true;
    }
}
...
Рейтинг: 0 / 0
21.09.2014, 18:08
    #38753003
Awaiter
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите понять async-await
codearticles.ru,

спасибо
...
Рейтинг: 0 / 0
24.09.2014, 21:39
    #38756753
Awaiter
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите понять async-await
Еще вопрос.
async-awayt корректно работают в циклах ?
...
Рейтинг: 0 / 0
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Помогите понять async-await / 10 сообщений из 10, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]