Гость
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / async / await and exception handling / 25 сообщений из 51, страница 1 из 3
26.01.2017, 16:02
    #39392223
mikron
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async / await and exception handling
Идея простая, по событию запускаем задачу на пуле задач для обработки действия. Пользователю показываю модалный диалог в котором отображаю прогресс. По завершению процесса закрываю диалог и выполнение идют дальше.
Пытаюсь пременить 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.
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                using (var dialog = new FormDialog())
                {
                    var task = DoItNowAsync(dialog);
                    dialog.ShowDialog(this);
                    task.Wait();     // It dosn't work as expected
                    // await task;   // May be so? But it not intension
                }
            }
            catch (Exception ex)
            {
                textBox1.Text = e.ToString();
            }
        }

        private async Task DoItNowAsync(Form dialog)
        {
            await Task.Run(() => { 
                Thread.Sleep(2000);
                throw new ApplicationException("Yep!");
                return true;
            });
            dialog.DialogResult = DialogResult.OK;
        }
    }



Что не получается: если во время обработки процесса происходит исключение то я хочу его обрабатывать в наружнем метчоде, (том, который вызывает async метод).
Пока получается только "Unhandled Exception"
Подскаычите, куда смотрет.
...
Рейтинг: 0 / 0
26.01.2017, 16:19
    #39392248
vb_sub
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async / await and exception handling
mikron,
смотрел на ютубе уроки по C#
https://www.youtube.com/channel/UCmdZlsCXz57nazOdp_o5wAg
...
Рейтинг: 0 / 0
26.01.2017, 16:21
    #39392253
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async / await and exception handling
mikron,

button1_Click должен быть async:

Код: c#
1.
private async void button1_Click(object sender, EventArgs e)



и тогда можно будет просто сделать

Код: c#
1.
await DoItNowAsync(dialog);



без task и Wait. И тогда получишь своё исключение.
...
Рейтинг: 0 / 0
26.01.2017, 16:38
    #39392280
Roman Mejtes
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async / await and exception handling
Использовать Tread.Sleep() в тасках ПЛОХАЯ идея! используйте await Task.Delay(ms) или Task.Delay(ms).Wait();
...
Рейтинг: 0 / 0
26.01.2017, 16:40
    #39392286
Т-Миронов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async / await and exception handling
mikron,

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
        private async Task DoItNowAsync(Form dialog)
        {
try{
            await Task.Run(() => { 
                Thread.Sleep(2000);
                throw new ApplicationException("Yep!");
                return true;
            });
}
catch{}
            dialog.DialogResult = DialogResult.OK;
        }
...
Рейтинг: 0 / 0
26.01.2017, 18:07
    #39392379
mikron
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async / await and exception handling
hVosttmikron,

button1_Click должен быть async:

Код: c#
1.
private async void button1_Click(object sender, EventArgs e)



и тогда можно будет просто сделать

Код: c#
1.
await DoItNowAsync(dialog);



без task и Wait. И тогда получишь своё исключение.
Так делать нельзя. В принципе конечно можно, но работать будет не так как надо.
Когда по твоему выполнится dialog.ShowDialog(this);
...
Рейтинг: 0 / 0
26.01.2017, 18:09
    #39392381
mikron
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async / await and exception handling
Roman MejtesИспользовать Tread.Sleep() в тасках ПЛОХАЯ идея! используйте await Task.Delay(ms) или Task.Delay(ms).Wait();
Тут ежу понатно, что sleep только для демонстрации.
...
Рейтинг: 0 / 0
26.01.2017, 18:23
    #39392392
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async / await and exception handling
mikronТак делать нельзя. В принципе конечно можно, но работать будет не так как надо.
Когда по твоему выполнится dialog.ShowDialog(this);

Код: c#
1.
2.
3.
4.
5.
6.
7.
public static async Task<DialogResult> ShowDialogAsync(this Form @this)
        {
            await Task.Yield();
            if (@this.IsDisposed)
                return DialogResult.OK;
            return @this.ShowDialog();
        }
...
Рейтинг: 0 / 0
26.01.2017, 18:42
    #39392405
mikron
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async / await and exception handling
hVosttmikronТак делать нельзя. В принципе конечно можно, но работать будет не так как надо.
Когда по твоему выполнится dialog.ShowDialog(this);

Код: c#
1.
2.
3.
4.
5.
6.
7.
public static async Task<DialogResult> ShowDialogAsync(this Form @this)
        {
            await Task.Yield();
            if (@this.IsDisposed)
                return DialogResult.OK;
            return @this.ShowDialog();
        }


А это тут причем? Куда это вставлять?
Идею не понял. Или я дурак или идея глупая.
Приведи пример кода (или мой кусок исправь)
...
Рейтинг: 0 / 0
26.01.2017, 18:54
    #39392414
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async / await and exception handling
mikronА это тут причем? Куда это вставлять?

Что тут непонятного?

dialog.ShowDialogAsync()
...
Рейтинг: 0 / 0
26.01.2017, 18:58
    #39392419
mikron
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async / await and exception handling
hVosttmikronТак делать нельзя. В принципе конечно можно, но работать будет не так как надо.
Когда по твоему выполнится dialog.ShowDialog(this);

Код: c#
1.
2.
3.
4.
5.
6.
7.
public static async Task<DialogResult> ShowDialogAsync(this Form @this)
        {
            await Task.Yield();
            if (@this.IsDisposed)
                return DialogResult.OK;
            return @this.ShowDialog();
        }


Kак работает async ты не понимаеш. Не растраивайся, нас милион.
...
Рейтинг: 0 / 0
26.01.2017, 19:01
    #39392422
mikron
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async / await and exception handling
hVosttmikronА это тут причем? Куда это вставлять?

Что тут непонятного?

dialog.ShowDialogAsync()

Просто заменить одну строчку dialog.ShowDialog(this)? Получим блокировку.
...
Рейтинг: 0 / 0
26.01.2017, 19:32
    #39392436
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async / await and exception handling
mikronKак работает async ты не понимаеш. Не растраивайся, нас милион.
mikronПросто заменить одну строчку dialog.ShowDialog(this)? Получим блокировку.

Давненько не работал с WinForms, но я был бы очень рад, если ты пояснишь свою мысль.
Возможно я ошибаюсь.

Можно ещё через Dispatcher решить задачу.
...
Рейтинг: 0 / 0
26.01.2017, 21:10
    #39392505
ВМоисеев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async / await and exception handling
>mikron, сегодня, 16:02 http://www.sql.ru/forum/actualutils.aspx?action=gotomsg&tid=1247548&msg=20149979] [20149979]

>Идея простая, по событию запускаем задачу ...

Ситуация аналогичная - построение выборки с Oracle больше минуты, в интерактивном-то приложении. Полный облом. Надо заполнить ожидание. Подошел такой вариант - демонстратор процесса ожидания есть вращающийся земной шарик и прогрессбар.
В одном пользовательском приложении: смысловое приложение - WinForm, демонстратор - WPF.

Поступил так:

Код: 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.
    //-- Демонстратор процесса ожидания получения данных
    private void f_Start() {
      prc_Ожидание = new Process();
      prc_Ожидание.StartInfo.FileName = гп.pth_Решения + @"\wpf_Ожидание.exe";
      prc_Ожидание.StartInfo.Arguments = "40"; //-- примерное время построения выборки + гак
      prc_Ожидание.Start();
    }

    private void btn_Продолжим_Click(object sender, EventArgs e) {
      //-- Дата в имени формы
      гп.оПребываниеТБ.dt_Пребывание= dtp_Пребывание.Value;

      //-- Запускаем в параллельном режиме формирование выборки
      this.WindowState = FormWindowState.Minimized;
      //await Task.Run(new Action(f_Выборка));
      var tk_v = Task.Run(() => f_Выборка());

      //-- Запустим демонстратор процесса ожидания получения данных
      //var tk_s = Task.Run(() => f_Start());
      f_Start();

      //-- Ожидаем завершение построения выборки
      tk_v.Wait();

      //-- Остановим демонстратор процесса получения данных
      foreach (Process clsProcess in Process.GetProcesses())
        if (clsProcess.ProcessName == "wpf_Ожидание") prc_Ожидание.Kill();
      if (prc_Ожидание != null) {
        prc_Ожидание.Dispose();
        prc_Ожидание.Close();
        prc_Ожидание = null;
      }

      this.Dispose();
      this.Close();
    }



С уважением,
Владимир
...
Рейтинг: 0 / 0
26.01.2017, 21:11
    #39392506
refreg
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async / await and exception handling
mikron,

Думаю, с await здесь не прокатит. По старинке (Task.ContinueWith) не подходит?
...
Рейтинг: 0 / 0
27.01.2017, 00:08
    #39392593
mikron
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async / await and exception handling
hVosttmikronKак работает async ты не понимаеш. Не растраивайся, нас милион.
mikronПросто заменить одну строчку dialog.ShowDialog(this)? Получим блокировку.

Давненько не работал с WinForms, но я был бы очень рад, если ты пояснишь свою мысль.

В DoItNowAsync после успешного завершения await необходимо переключение контекста (SynchrinisationConext)
но для этого необходимо что-бы запустился message pump.
В моей реализации это достигается dialog.ShowDialog(this);
В твоей реализации этого никогда не произойдёт т.к. поток просто встанет в task.Wait();
И твой this.ShowDialog() из ShowDialogAsync тоже никда не запустится, по той-же причине.

Просто проверь, код же ест.
...
Рейтинг: 0 / 0
27.01.2017, 02:39
    #39392620
ВМоисеев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async / await and exception handling
>mikron, сегодня, 00:08 http://www.sql.ru/forum/actualutils.aspx?action=gotomsg&tid=1247548&msg=20151610] [20151610]
>...В моей реализации это достигается dialog.ShowDialog(this)...

Вы рассматривали граничный вариант? Проходит?

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
        private async Task DoItNowAsync(Form dialog)   {
            await Task.Run(() => { 
                //--!! Thread.Sleep(2000);
                throw new ApplicationException("Yep!");
                return true;
            });
            dialog.DialogResult = DialogResult.OK;
        }



С уважением,
Владимир
...
Рейтинг: 0 / 0
27.01.2017, 09:28
    #39392695
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async / await and exception handling
mikronПросто проверь, код же ес

Я не поленился, и проверил.

Картинка и код:

Код: 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.
50.
51.
52.
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private async void button1_Click(object sender, EventArgs e)
        {
            try
            {
                using (var dialog = new FormDialog())
                {
                    var showDialogTask = dialog.ShowDialogAsync();
                    await DoItNowAsync();
                    await showDialogTask;
                }
            }
            catch (Exception ex)
            {
                textBox1.Text = ex.ToString();
            } 
        }

        private async Task DoItNowAsync()
        {
            await Task.Run(() => {
                Thread.Sleep(2000);
                throw new ApplicationException("Yep!");
                return true;
            });
        }
    }

    public static class SomeExtensions
    {
        public static async Task<DialogResult> ShowDialogAsync(this Form @this)
        {
            await Task.Yield();
            if (@this.IsDisposed)
                return DialogResult.OK;
            return @this.ShowDialog();
        }
    }
}
...
Рейтинг: 0 / 0
27.01.2017, 09:29
    #39392696
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async / await and exception handling
mikronВ DoItNowAsync после успешного завершения await необходимо переключение контекста (SynchrinisationConext)
но для этого необходимо что-бы запустился message pump.
В моей реализации это достигается dialog.ShowDialog(this);
В твоей реализации этого никогда не произойдёт т.к. поток просто встанет в task.Wait();
И твой this.ShowDialog() из ShowDialogAsync тоже никда не запустится, по той-же причине.

Ты какие-то нелепейшие глупости говоришь.
У меня всё работает, я изначально привёл тебе решение, но ты даже не стал проверять.
...
Рейтинг: 0 / 0
27.01.2017, 10:30
    #39392773
mikron
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async / await and exception handling
hVosttmikronВ DoItNowAsync после успешного завершения await необходимо переключение контекста (SynchrinisationConext)
но для этого необходимо что-бы запустился message pump.
В моей реализации это достигается dialog.ShowDialog(this);
В твоей реализации этого никогда не произойдёт т.к. поток просто встанет в task.Wait();
И твой this.ShowDialog() из ShowDialogAsync тоже никда не запустится, по той-же причине.

Ты какие-то нелепейшие глупости говоришь.
У меня всё работает, я изначально привёл тебе решение, но ты даже не стал проверять.
Ты просил обяснить, но видно не в состоянии понять. Начнём с первого предложения, не пропуская слов.
mikronВ DoItNowAsync после успешного завершения await необходимо переключение контекста (SynchrinisationConext)
Переводу на доступный - закомнитруй выброс исключения.
...
Рейтинг: 0 / 0
27.01.2017, 10:36
    #39392788
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async / await and exception handling
mikronmikronВ DoItNowAsync после успешного завершения await необходимо переключение контекста (SynchrinisationConext)
Переводу на доступный - закомнитруй выброс исключения.

Я всё равно не понимаю, что ты хочешь сказать и к чему ведёшь.

Вот твой изначальный вопрос:

mikronЧто не получается: если во время обработки процесса происходит исключение то я хочу его обрабатывать в наружнем метчоде, (том, который вызывает async метод).
Пока получается только "Unhandled Exception"
Подскаычите, куда смотрет.

Я тебе выше привёл полное решение, в котором твоё исключение попадает в «наружний метод» в чистом виде.

Если мне не веришь, скопируй код, который я тебе привёл и выполни. Увидишь отлов своего исключения.

Тем более ты мне что-то говорил, что это работать не будет, что будет какая-то блокировка — это не правда. Всё работает, никаких блокировок.
...
Рейтинг: 0 / 0
27.01.2017, 10:41
    #39392798
mikron
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async / await and exception handling
hVostt,

Стоп, только сейчас заметил, ты изменил метод DoItNowAsync, убрал присваивание dialogResult. Посмотрю позже.
...
Рейтинг: 0 / 0
27.01.2017, 11:01
    #39392821
mikron
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async / await and exception handling
hVosttmikronА это тут причем? Куда это вставлять?

Что тут непонятного?

dialog.ShowDialogAsync()

Я не люблю головоломок из области найди отличия
Код: 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.
1. 
private void button1_Click(object sender, EventArgs e)
vs.
private async void button1_Click(object sender, EventArgs e)

2.
                    var task = DoItNowAsync(dialog);
                    dialog.ShowDialog(this);
                    task.Wait();     // It dosn't work as expected
 vs.
                    var showDialogTask = dialog.ShowDialogAsync();
                    await DoItNowAsync();
                    await showDialogTask;

3.
 private async Task DoItNowAsync(Form dialog)
        {
            await Task.Run(() => { 
                Thread.Sleep(2000);
                throw new ApplicationException("Yep!");
                return true;
            });
            dialog.DialogResult = DialogResult.OK;
        }
vs.
private async Task DoItNowAsync()
        {
            await Task.Run(() => {
                Thread.Sleep(2000);
                throw new ApplicationException("Yep!");
                return true;
            });
        }
...
Рейтинг: 0 / 0
27.01.2017, 11:05
    #39392826
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async / await and exception handling
mikronhVostt,

Стоп, только сейчас заметил, ты изменил метод DoItNowAsync, убрал присваивание dialogResult. Посмотрю позже.

Форма диалога должна сама устанавливать значение этого свойства и возвращать результат, установка этого свойства внешним кодом это жутковатый грубый костыль. Конечно я снёс это безобразие.
...
Рейтинг: 0 / 0
27.01.2017, 11:06
    #39392828
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
async / await and exception handling
mikronЯ не люблю головоломок из области найди отличия

Обо всех отличиях было сказано выше, про async и метод расширения, про то, что task.Wait надо убрать я тоже писал. Не люблю повторяться, просто применил всё, что было сказано.

Про присваивание диалогу значения свойства, тоже написал, но можно и присвоить если очень хочется.
...
Рейтинг: 0 / 0
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / async / await and exception handling / 25 сообщений из 51, страница 1 из 3
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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