powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / C# async... await
25 сообщений из 317, страница 8 из 13
C# async... await
    #39573955
ВМоисеев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>ВМоисеев,
очепятка - в случае await без Task.Run
...
Рейтинг: 0 / 0
C# async... await
    #39573960
ViPRos
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВМоисеев>ВМоисеев,
очепятка - в случае await без Task.Run
ну тебе с первого дня про то и говорили, что бы пользовался асинхронными методами
...
Рейтинг: 0 / 0
C# async... await
    #39573967
ViPRos
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Теперь смотрим на исходный код и дивимся, а паттерн то знакомый!!!

Код: 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.
 new public Task<SqlDataReader> ExecuteReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken) {
 
            Bid.CorrelationTrace("<sc.SqlCommand.ExecuteReaderAsync|API|Correlation> ObjectID%d#, behavior=%d{ds.CommandBehavior}, ActivityID %ls\n", ObjectID, (int)behavior);
            SqlConnection.ExecutePermission.Demand();
 
            TaskCompletionSource<SqlDataReader> source = new TaskCompletionSource<SqlDataReader>();
 
            CancellationTokenRegistration registration = new CancellationTokenRegistration();
            if (cancellationToken.CanBeCanceled) {
                if (cancellationToken.IsCancellationRequested) {
                    source.SetCanceled();
                    return source.Task;
                }
                registration = cancellationToken.Register(CancelIgnoreFailure);
            }
 
            Task<SqlDataReader> returnedTask = source.Task;
            try {
                RegisterForConnectionCloseNotification(ref returnedTask);
 
                Task<SqlDataReader>.Factory.FromAsync(BeginExecuteReaderAsync, EndExecuteReaderAsync, behavior, null).ContinueWith((t) => {
                    registration.Dispose();
                    if (t.IsFaulted) {
                        Exception e = t.Exception.InnerException;
                        source.SetException(e);
                    }
                    else {
                        if (t.IsCanceled) {
                            source.SetCanceled();
                        }
                        else {
                            source.SetResult(t.Result);
                        }
                    }
                }, TaskScheduler.Default);
            }
            catch (Exception e) {
                source.SetException(e);
            }
 
            return returnedTask;
        }
...
Рейтинг: 0 / 0
C# async... await
    #39573968
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВМоисеев>Petro123, сегодня, 17:55 http://www.sql.ru/forum/actualutils.aspx?action=gotomsg&tid=1280515&msg=21053109][21053094]
>Если есть асинхронный метод в драйвере...
Использую провайдер Devart dotConnect for Oracle, здесь есть. Похоже и для Posgre тоже
Ну, если будут ошибки и захочешь Все завернуть без асинк в дровах - заходи))).
У меня await + task.run + лябда вместе с коннектами.
Работает.
...
Рейтинг: 0 / 0
C# async... await
    #39573971
ВМоисеев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>refreg, сегодня, 18:19 http://www.sql.ru/forum/actualutils.aspx?action=gotomsg&tid=1280515&msg=21053164][21053164]
>Обрати внимание, что тут 3 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.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
using System;
using System.Data;
using Devart.Data.Oracle;
using System.Threading.Tasks;

namespace ns_ГИС {
  public delegate void dlg_sp(dlg_RowToEntity RowToEntity);
  public delegate void dlg_RowToEntity(IDataRecord reader);

  public static class wsp {
    static int nRow;
    static OracleDataReader reader;

    //-- Обработка строк выборки select
    public static async void sp_Sel(dlg_RowToEntity RowToEntity) {
      while (await reader.ReadAsync()) {
        nRow++;
        if (nRow == гп.max_Выборка) break;   //-- Это максимум что можем отобразить, надо уточнять запрос
        RowToEntity(reader);
      }
    }
    //-- Обработка строки выборки insert
    public static async void sp_Ins(dlg_RowToEntity RowToEntity) {
      if (await reader.ReadAsync()) RowToEntity(reader);
    }
    //-- Обработка строки выборки update
    public static async void sp_Upd(dlg_RowToEntity RowToEntity) {
      int i = 0;
      if (await reader.ReadAsync()) {
        i = reader.FieldCount;
        i = (int)reader.GetInt32(i-1);
        RowToEntity(reader);
        if (i != 1) throw new Exception("Запись кем то изменена");
      }
    }
    //-- Обработка строки выборки delete
    public static async void sp_Del(dlg_RowToEntity RowToEntity) {
      if (await reader.ReadAsync()) {
        //-- Если читаем якобы удаленную строку, то удаления нет
        RowToEntity(reader);
        throw new Exception("Запись кем то изменена");
      }
    }

    //-- Выполнение хранимой процедуры
    public static async Task Entity_SP(string spname, dlg_sp sp, OracleParameter[] asp, dlg_RowToEntity RowToEntity) {
      nRow = 0;  //-- Число строк в выборке
      reader = null;

      using (OracleConnection connection = new OracleConnection(гп.str_Соединение)) {
        connection.Open();
        OracleCommand command = new OracleCommand("", connection);
        command.Parameters.Clear();
        command.Parameters.AddRange(asp);
        command.CommandText = spname;
        command.CommandType = CommandType.StoredProcedure;

        using (reader = (OracleDataReader)await command.ExecuteReaderAsync()) {
          //-- Формируем коллекцию из выборки
          sp(RowToEntity); //-- Обратный вызов
        }
      }
    }
  }
  . . .
    //-- Строку выбоки из таблиц базы данных отражаем на entity 
    //-- 0.pk_puska, 1.nv, 2.dt_puska, 3.nom_puska, 4.strana_puska, 5.mesto_puska 
    //-- 6.lng_s, 7.lat_s, 8.lng_p, 9.lat_p, 10.reg
    private void RowToEntity(IDataRecord record) {
      xrow = new row_Entity() {
        chb_Entity = false,
        pk_Entity = record.GetInt64(0),              //-- суррогатный ключ
        nv = record.GetInt64(1),                     //-- Для оптимистической блокировки

        dt_Пуск = record.GetDateTime(2),
        str_НомерПуска = record.GetString(3).Trim(),
        str_СтранаПуска = record.GetString(4).Trim(),
        str_МестоПуска = record.GetString(5).Trim(),
        fl_Lng_s = record.GetFloat(6),                 //-- Долгота объекта
        fl_Lat_s = record.GetFloat(7),                 //-- Широта объекта
        fl_Lng_p = record.GetFloat(8),                 //-- Долгота объекта
        fl_Lat_p = record.GetFloat(9),                 //-- Широта объекта
        reg = null
      };
      if (!record.IsDBNull(10)) {
        byte[] xbt = new byte[84];
        record.GetBytes(10, 0, xbt, 0, 84);
        xrow.reg = xbt;
      } 
      lst_Entity.Add(xrow);
    }
    . . .


...
Рейтинг: 0 / 0
C# async... await
    #39573973
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВМоисеев
Код: c#
1.
sp(RowToEntity)


У тебя там к ГУИ нет вызовов?
...
Рейтинг: 0 / 0
C# async... await
    #39573978
refreg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВМоисеев
Код: c#
1.
await reader.ReadAsync()


Попробуй везде (в библиотечном коде, в котором точно нет UI) заменить на
Код: c#
1.
await reader.ReadAsync().ConfigureAwait(false)
...
Рейтинг: 0 / 0
C# async... await
    #39573983
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВМоисеев,
Ты раньше в ветке Оракла пел что у тебя временные таблицы в хранимке и тормозит.
Тут зачем асинхронность? Сколько в цифрах?
...
Рейтинг: 0 / 0
C# async... await
    #39573986
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
refreg
Код: c#
1.
await reader.ReadAsync().ConfigureAwait(false)



это ничего не изменит, хотя может спасти от дедлоков в некоторых случаях и работать будет по-быстрее, так как не будет восстанавливаться контекст в continuation
...
Рейтинг: 0 / 0
C# async... await
    #39573989
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВМоисеев,

рекомендую ознакомиться вот этой статьёй

https://stephenhaunts.com/2014/10/14/using-async-and-await-to-update-the-ui-thread/
...
Рейтинг: 0 / 0
C# async... await
    #39574011
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt,
Посмотрел.
У меня не выйдет вариант с асинхронными дровами методами.
У меня ГИС. 100 слоев карты это 100 сущностей хибернейт.
Читает из базы адаптер 15сек. И далее в оперативке строится слой 2мин.
Поэтому я завернул Весь код в поток.
for layer .....count{
NewLayerAsync(...
}
Где и сколько тормозит у автора хз.
Он идет на 100 страниц. Либо обучается)).
...
Рейтинг: 0 / 0
C# async... await
    #39574015
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Petro123,

ну вообще для десткопа не так уж критично экономить на потоках
...
Рейтинг: 0 / 0
C# async... await
    #39574017
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt,
Тут пул экономит. Я ему 100 раз task.run лямбда, а он более 20 не апускает))).
Меня устраивает.
Словари пришлось поменять на потокозащищенные.
...
Рейтинг: 0 / 0
C# async... await
    #39574018
ВМоисеев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>Petro123, сегодня, 19:25 http://www.sql.ru/forum/actualutils.aspx?action=gotomsg&tid=1280515&msg=21053348] [21053348]

>...У меня ГИС. 100 слоев карты ...
Хоть и не по теме, но интересно - это Вы о чем?
...
Рейтинг: 0 / 0
C# async... await
    #39574023
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВМоисеев>Petro123, сегодня, 19:25 http://www.sql.ru/forum/actualutils.aspx?action=gotomsg&tid=1280515&msg=21053348] [21053348]

>...У меня ГИС. 100 слоев карты ...
Хоть и не по теме, но интересно - это Вы о чем?
Проект на работе.
...
Рейтинг: 0 / 0
C# async... await
    #39574024
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВМоисеев,
Ты сам то когда про свой уточнять будешь?
Или закрывай тему.
...
Рейтинг: 0 / 0
C# async... await
    #39574116
ВМоисеев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>ВМоисеев, сегодня, 18:41 http://www.sql.ru/forum/actualutils.aspx?action=gotomsg&tid=1280515&msg=21053225][21053225]
Раньше не мог аккуратно тестировать хранимую процедуру Oracle - не знал как реализовать задержку.
Спасибо коллеге за процедуру:
-- Задержка
Код: plsql
1.
2.
3.
 procedure my_sleep( p_sleep in number )
 as language java
 name 'java.lang.Thread.sleep( long )';


Теперь могу тестировать и так:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
 -- Выборка из таблицы Strani_Puskov с параметрами
 procedure Strani_Puskov_Sql(
   cur_viborka out t_cursor
   ,x_Strana_Puska in varchar2
 )
 as
  sql_sel varchar2(2000) := '
  SELECT pk_Strana_Puska,nv,Strana_Puska,sk
  FROM tbl_Strani_Puskov
  WHERE (pk_Strana_Puska<>0)';
  sel1 varchar2(50) := ' AND Strana_Puska LIKE' || '''' || x_Strana_Puska || '''';

 begin
  if(x_Strana_Puska is not null) then
   sql_sel := sql_sel || sel1;
  end if;

  sql_sel := sql_sel || ' ORDER BY SK,Strana_Puska';

  -- Тест
  [color=red]my_sleep(9000);[/color]

  open cur_viborka for sql_sel;
 end Strani_Puskov_Sql;
...
Рейтинг: 0 / 0
C# async... await
    #39574122
refreg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttrefreg
Код: c#
1.
await reader.ReadAsync().ConfigureAwait(false)

это ничего не изменит, хотя может спасти от дедлоков в некоторых случаях и работать будет по-быстрее, так как не будет восстанавливаться контекст в continuation

Смотри, что я имел ввиду (добрался, до компа написать тестовую хрень):
Код: 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.
        private async void button1_Click(object sender, EventArgs e)
        {
            textBox1.Text = @"Start";

            Debug.WriteLine("UI:" + Thread.CurrentThread.ManagedThreadId);
            // var k = await Method().ConfigureAwait(true);            
            var k = await Method2().ConfigureAwait(true);
            Debug.WriteLine("IsUI" + Thread.CurrentThread.ManagedThreadId);

            textBox1.Text = @"Stop. Result is " + k;
        }

        private async Task<int> Method()
        {
            await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(true);
            Debug.WriteLine(Thread.CurrentThread.ManagedThreadId);
            await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(true);
            Debug.WriteLine(Thread.CurrentThread.ManagedThreadId);
            await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(true);
            Debug.WriteLine(Thread.CurrentThread.ManagedThreadId);
            await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(true);
            Debug.WriteLine(Thread.CurrentThread.ManagedThreadId);

            return 5;
        }

        private async Task<int> Method2()
        {
            await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(false);
            Debug.WriteLine(Thread.CurrentThread.ManagedThreadId);
            await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(false);
            Debug.WriteLine(Thread.CurrentThread.ManagedThreadId);
            await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(false);
            Debug.WriteLine(Thread.CurrentThread.ManagedThreadId);
            await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(false);
            Debug.WriteLine(Thread.CurrentThread.ManagedThreadId);

            return 5;
        }



В случае, Method, вывод такой:
Код: plaintext
1.
2.
3.
4.
5.
UI:1
1
1
1
1
IsUI1

В случае Method2, такой:
Код: plaintext
1.
2.
3.
4.
5.
UI:1
4
5
4
5
IsUI1
...
Рейтинг: 0 / 0
C# async... await
    #39574165
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВМоисеев,
- LIKE убрать
- склейку строк через || убрать
Проверить эффект через план выполнения.
Удивится тому, что может асинхронность и не нужна.
...
Рейтинг: 0 / 0
C# async... await
    #39574166
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВМоисеевЗадержка
Нужно еще в нужное место ставить задержку.
Видел у меня выше тормоз был не в бд а в оперативке в БЛ.
...
А в бд еще эффективнее ГЕНЕРАЦИЯ тестовых данных в табличках.
...
Рейтинг: 0 / 0
C# async... await
    #39574167
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЗЫ.. Я удивляюсь, зачем для select вообще хранимка?
В шарпе нет АппСервера?
...
Рейтинг: 0 / 0
C# async... await
    #39574169
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
refregВМоисеев
Код: c#
1.
await reader.ReadAsync()



Попробуй везде (в библиотечном коде, в котором точно нет UI) заменить на
Код: c#
1.
await reader.ReadAsync().ConfigureAwait(false)

вроде тут обычный прикладной код. Где должен быть лаконизм и минимум технического кода.
Значит это лишнее.
Не?
...
Рейтинг: 0 / 0
C# async... await
    #39574177
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
refregВ случае, Method, вывод такой:
Код: plaintext
1.
2.
3.
4.
5.
UI:1
1
1
1
1
IsUI1
В случае Method2, такой:
Код: plaintext
1.
2.
3.
4.
5.
UI:1
4
5
4
5
IsUI1


Так всё верно, continuation выполняется на любом первом свободном потоке без восстановления контекста синхронизации, именно благодаря этому не будет дедлоков, если кто-то сделал где-то Wait
...
Рейтинг: 0 / 0
C# async... await
    #39574180
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
refreg,

внутри внешних методов топикастера UI поток не нужен, и да, ConfigureAwait(false) надо делать всегда и везде, кроме основного потока исполнения. неудобный синтаксис, лучше бы атрибут сделали или freeasync какой-нибудь ))
...
Рейтинг: 0 / 0
C# async... await
    #39574188
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttименно благодаря этому не будет дедлоков, если кто-то сделал где-то Wait
Вот оно что. Вы все про костыли к старому коду? Тогда проехали. Ни мне, ни ТС это не надо.
У нас Wait нету в старом коде. А до ГУИ очень близко. Могу вызвать след.строкой после await.
...
Рейтинг: 0 / 0
25 сообщений из 317, страница 8 из 13
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / C# async... await
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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