Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / WinForms, .Net Framework Новый топик    Ответить
Топик располагается на нескольких страницах: 1 2      [все]
 От чего может виснуть этот код?  [new]
Бариску Нацарство
Member

Откуда:
Сообщений: 11
Примерно так:

В form_Load:

new Task(async () =>
{
  await LoadSomeEntities1().ConfigureAwait(false);
  await LoadSomeEntities2().ConfigureAwait(false);
  await LoadSomeEntities3().ConfigureAwait(false);
}).RunSynchronously();


Форма загружается, всё отрабатывает, всё загружено. Никаких проблем!

В combobox_selectedIndexChanged:

LoadSomeEntities3().ConfigureAwait(false).GetAwaiter().GetResult();


А в самой функции:

async Task LoadSomeEntities3()
{
  trvTreeView.SuspendLayout();
  trvTreeView.BeginUpdate();
  trvTreeView.Nodes.Clear();

  await ReadEntitesFromDB().ConfigureAwait(false); // Но если здесь убрать await и добавить .GetAwaiter().GetResult(), то не виснет
  foreach(var entity in entities)
  {
    if(trvTreeView.InvokeRequired)
    {
      trvTreeView.Invoke((MethodDelegate) delegate // виснет здесь только при выборе значения в комбобоксе
      {
        trvTreeView.Nodes.Add(entity.Name);
      });
    }
    else
    {
       trvTreeView.Nodes.Add(entity.Name);
    }
  }

  if(trvTreeView.InvokeRequired)
  {
    trvTreeView.Invoke((MethodDelegate) delegate 
    {
      trvTreeView.EndUpdate();
      trvTreeView.ResumeLayout();
    }
  }
  else
  {
    trvTreeView.EndUpdate();
    trvTreeView.ResumeLayout();
  }
}


Но стоит сменить значение комбобокса, как тот же самый код виснет на входе в делегат. Чем отличается вызов этого кода при пользовательском вводе от вызова при загрузке формы?

В обоих случаях InvokeRequired = true, соответственно всегда отрабатывает делегат.

Сообщение было отредактировано: 7 апр 21, 20:36
7 апр 21, 20:39    [22305685]     Ответить | Цитировать Сообщить модератору
 Re: От чего может виснуть этот код?  [new]
hVostt
Member

Откуда:
Сообщений: 19318
Бариску Нацарство
await ReadEntitesFromDB().ConfigureAwait(false); // Но если здесь убрать await и добавить .GetAwaiter().GetResult(), то не виснет


потому что так делать нельзя, объяснять долго, нудно, всё это можно найти и почитать в документации.

непонятно зачем так делаете, это просто эксперименты?

https://stackoverflow.com/questions/5095183/how-would-i-run-an-async-taskt-method-synchronously
7 апр 21, 21:45    [22305699]     Ответить | Цитировать Сообщить модератору
 Re: От чего может виснуть этот код?  [new]
Бариску Нацарство
Member

Откуда:
Сообщений: 11
что значит нельзя? так делают все и везде. в чём конкретно претензия?
и зачем мне ссылка на синхронное исполнение асинхронного вызова? синхронно-то оно и так работает.
7 апр 21, 23:08    [22305726]     Ответить | Цитировать Сообщить модератору
 Re: От чего может виснуть этот код?  [new]
hVostt
Member

Откуда:
Сообщений: 19318
Бариску Нацарство
что значит нельзя?


то и значит.

Бариску Нацарство
так делают все и везде. в чём конкретно претензия?


new Task(async () =>
{
  await LoadSomeEntities1().ConfigureAwait(false);
  await LoadSomeEntities2().ConfigureAwait(false);
  await LoadSomeEntities3().ConfigureAwait(false);
}).RunSynchronously();


так даже в дремучем колхозе делать моветон.


Бариску Нацарство
и зачем мне ссылка на синхронное исполнение асинхронного вызова? синхронно-то оно и так работает.


у вас асинхронный метод

async Task LoadSomeEntities3()


зачем вы в этом методе асинхронный метод пытаетесь вызвать "синхронно"?

await ReadEntitesFromDB().ConfigureAwait(false); // Но если здесь убрать await и добавить .GetAwaiter().GetResult(), то не виснет


зачем убирать await и добавлять GetResult()? это во-первых неправильно, что как бы подтверждается тем, что "виснет", во-вторых.. зачем? это для чего?
7 апр 21, 23:23    [22305737]     Ответить | Цитировать Сообщить модератору
 Re: От чего может виснуть этот код?  [new]
hVostt
Member

Откуда:
Сообщений: 19318
Бариску Нацарство,

и зачем вы везде .ConfigureAwait(false) добавляете? при чём там, где как раз этого делать нельзя.
7 апр 21, 23:24    [22305738]     Ответить | Цитировать Сообщить модератору
 Re: От чего может виснуть этот код?  [new]
petalvik
Member

Откуда:
Сообщений: 712
Бариску Нацарство,

private async void Form1_LoadAsync(object sender, EventArgs e)
{
    await LoadSomeEntities1().ConfigureAwait(false);
    await LoadSomeEntities2().ConfigureAwait(false);
    await LoadSomeEntities3().ConfigureAwait(false);
}

Не нужно их оборачивать в Task и запускать синхронно.
При желании, можно написать так:

private async void Form1_LoadAsync(object sender, EventArgs e)
{
    var t1 = LoadSomeEntities1();
    var t2 = LoadSomeEntities2();
    var t3 = LoadSomeEntities3();
    await Task.WhenAll(t1, t2, t3);
}

Так все три метода будут выполняться одновременно, то есть общее выполнение будет быстрее. Но это если они не обращаются к одним и тем же объектам.


async Task LoadSomeEntities1()
{
    trvTreeView.SuspendLayout();
    trvTreeView.BeginUpdate();
    trvTreeView.Nodes.Clear();

    // Возвращаемся в тот же контекст синхронизации,
    // поэтому вызовы Invoke не нужны.
    await ReadEntitesFromDB();

    foreach (var entity in entities)
    {
        trvTreeView.Nodes.Add(entity.Name);
    }

    trvTreeView.EndUpdate();
    trvTreeView.ResumeLayout();
}

И это всё! Суть и красота асинхронности заключена в лаконичности, которую она позволяет.


private async void ComboBox_SelectedIndexChangedAsync(object sender, EventArgs e)
{
    await LoadSomeEntities3();            
}


Ничего не виснет, всё летает!

ЗЫ: у обработчиков событий в сигнатуре должно быть async.
7 апр 21, 23:58    [22305744]     Ответить | Цитировать Сообщить модератору
 Re: От чего может виснуть этот код?  [new]
hVostt
Member

Откуда:
Сообщений: 19318
petalvik
ЗЫ: у обработчиков событий в сигнатуре должно быть async.


да, void async-и поддержали только ради событий WinForms
8 апр 21, 01:39    [22305754]     Ответить | Цитировать Сообщить модератору
 Re: От чего может виснуть этот код?  [new]
Бариску Нацарство
Member

Откуда:
Сообщений: 11
Джон Скит из МС утверждает везде что на каждом асинхронном вызове должен висеть .ConfigureAwait(false).
Вы утверждаете, что это делает вызов синхронным. И кому верить?

> зачем убирать await и добавлять GetResult()? это во-первых неправильно, что как бы подтверждается тем, что "виснет", во-вторых.. зачем? это для чего?

чтобы не висло. Вы, кажется, всё перепутали: как "неправильно" не виснет. Как сейчас виснет.

Сообщение было отредактировано: 8 апр 21, 15:30
8 апр 21, 15:35    [22306023]     Ответить | Цитировать Сообщить модератору
 Re: От чего может виснуть этот код?  [new]
Бариску Нацарство
Member

Откуда:
Сообщений: 11
petalvik
Бариску Нацарство,
async Task LoadSomeEntities1()
{
    trvTreeView.SuspendLayout();
    trvTreeView.BeginUpdate();
    trvTreeView.Nodes.Clear();

    // Возвращаемся в тот же контекст синхронизации,
    // поэтому вызовы Invoke не нужны.
    await ReadEntitesFromDB();

    foreach (var entity in entities)
    {
        trvTreeView.Nodes.Add(entity.Name);
    }

    trvTreeView.EndUpdate();
    trvTreeView.ResumeLayout();
}

И это всё! Суть и красота асинхронности заключена в лаконичности, которую она позволяет.

ЗЫ: у обработчиков событий в сигнатуре должно быть async.


Сделал всё, как Вы советуете выше. Вроде бы всё работает, только две проблемы остались:

await ReadEntitesFromDB(); виснет, если не добавить .ConfigureAwait(false)

и всё-таки добавление нод в trvTreeView по-прежнему бросает исключение об обращении из другой нити, если не оставить .Invoke((MethodDelegate)
8 апр 21, 16:22    [22306049]     Ответить | Цитировать Сообщить модератору
 Re: От чего может виснуть этот код?  [new]
petalvik
Member

Откуда:
Сообщений: 712
Бариску Нацарство,

Вот этот код ошибочен:

private async void Form1_LoadAsync(object sender, EventArgs e)
{
    await LoadSomeEntities1().ConfigureAwait(false);
    await LoadSomeEntities2().ConfigureAwait(false);
    await LoadSomeEntities3().ConfigureAwait(false);
}

Здесь нужно убрать .ConfigureAwait(false). Потому что в этих методах происходит обращение к GUI-контролам.
Правильный код:

private async void Form1_LoadAsync(object sender, EventArgs e)
{
    await LoadSomeEntities1();
    await LoadSomeEntities2();
    await LoadSomeEntities3();
}


Теперь не будет бросать исключение.


Бариску Нацарство

await ReadEntitesFromDB(); виснет, если не добавить .ConfigureAwait(false)

Значит код в методе ReadEntitesFromDB() написан неправильно. Наверняка там тоже присобачено .GetAwaiter().GetResult() или что-то ещё. Покажи код.
8 апр 21, 16:37    [22306061]     Ответить | Цитировать Сообщить модератору
 Re: От чего может виснуть этот код?  [new]
petalvik
Member

Откуда:
Сообщений: 712
Бариску Нацарство,

И ещё. Вызовы trvTreeView.SuspendLayout(); и trvTreeView.ResumeLayout(); не нужны. Если, конечно, в тривью не добавляются дочерние контролы вызовом trvTreeView.Controls.Add(...);
8 апр 21, 16:43    [22306064]     Ответить | Цитировать Сообщить модератору
 Re: От чего может виснуть этот код?  [new]
Бариску Нацарство
Member

Откуда:
Сообщений: 11
petalvik
Бариску Нацарство,

Вот этот код ошибочен:


Спасибо, всё почистил, всё работает.
Объяснил бы ещё кто зачем тот самый Джон Скит везде пугает не использовать async void и настаивает чтобы на каждом await висел .ConfigureAwait(false). Я поначалу делал именно как Вы советуете, но меня затроллили и много лет заставляли добавлять .ConfigureAwait(false).
8 апр 21, 23:04    [22306217]     Ответить | Цитировать Сообщить модератору
 Re: От чего может виснуть этот код?  [new]
Shocker.Pro
Member

Откуда: ->|<- :адуктО
Сообщений: 22381
Бариску Нацарство
Объяснил бы ещё кто зачем тот самый Джон Скит везде пугает не использовать async void и настаивает чтобы на каждом await висел .ConfigureAwait(false). Я поначалу делал именно как Вы советуете, но меня затроллили и много лет заставляли добавлять .ConfigureAwait(false).
А не проще ли взять учебник и прочесть, что делает ConfigureAwait(false) и что такое контекст синхронизации и поток пользовательского интерфейса. Не перепечатывать же учебник на форум.
8 апр 21, 23:19    [22306223]     Ответить | Цитировать Сообщить модератору
 Re: От чего может виснуть этот код?  [new]
Сон Веры Павловны
Member

Откуда:
Сообщений: 6192
hVostt
да, void async-и поддержали только ради событий WinForms

Почему это? События есть не только в винформс, а много ещё где - в т.ч. в областях, вообще никак не связанных с GUI:
var timer = new System.Timers.Timer(TimeSpan.FromSeconds(1).TotalMilliseconds)
{
  AutoReset = true,
  Enabled = false
};
timer.Elapsed += TimerElapsed;
timer.Start();
...
static async void TimerElapsed(object sender, System.Timers.ElapsedEventArgs e)
{
  await Task.Delay(TimeSpan.FromSeconds(1));
  Console.WriteLine("Tick: {0}", DateTime.Now);
}
9 апр 21, 06:38    [22306255]     Ответить | Цитировать Сообщить модератору
 Re: От чего может виснуть этот код?  [new]
Shocker.Pro
Member

Откуда: ->|<- :адуктО
Сообщений: 22381
ТС ссылку-то не дал, а Джон Скит наверняка имел ввиду - не плодить собственные сигнатуры с async void. А от легаси никуда не денешься, потому это исключение. Да и про ConfugureAwait наверняка указывал те случаи, когда его нельзя применять. Но зачем вникать в детали - давай везде пихать.
9 апр 21, 09:35    [22306290]     Ответить | Цитировать Сообщить модератору
 Re: От чего может виснуть этот код?  [new]
hVostt
Member

Откуда:
Сообщений: 19318
Бариску Нацарство
Джон Скит из МС утверждает везде что на каждом асинхронном вызове должен висеть .ConfigureAwait(false).
Вы утверждаете, что это делает вызов синхронным. И кому верить?


ничего он такого не утверждает.
9 апр 21, 10:13    [22306309]     Ответить | Цитировать Сообщить модератору
 Re: От чего может виснуть этот код?  [new]
hVostt
Member

Откуда:
Сообщений: 19318
Сон Веры Павловны
Почему это? События есть не только в винформс, а много ещё где - в т.ч. в областях, вообще никак не связанных с GUI:


за пределами WinForms события лучше не использовать.
и вообще забыть про них как про страшный сон.
9 апр 21, 10:14    [22306310]     Ответить | Цитировать Сообщить модератору
 Re: От чего может виснуть этот код?  [new]
Сон Веры Павловны
Member

Откуда:
Сообщений: 6192
Shocker.Pro
ТС ссылку-то не дал, а Джон Скит наверняка имел ввиду - не плодить собственные сигнатуры с async void.

Об этом пишет не только Скит (который, кстати говоря, давно уже в гугле работает). Вот, например: https://docs.microsoft.com/en-us/archive/blogs/ptorr/async-exceptions-in-c
Причина достаточно банальна: void не содержит информации о контексте выполнения задачи, т.к. это void. И поэтому с void есть вот такое:
static async Task Main()
{
  AppDomain.CurrentDomain.UnhandledException += (s, e)
    => Console.WriteLine("UnhandledException: {0}", e.ExceptionObject);
  TaskScheduler.UnobservedTaskException += (s, e) =>
    Console.WriteLine("UnobservedTaskException: {0}", e);
  Console.WriteLine("Running TestTask");
  try
  {
    await TestTask();
  }
  catch (Exception e)
  {
    Console.WriteLine("TestTask error: {0}", e);
  }
  Console.WriteLine("Running TestVoid");
  try
  {
    TestVoid(); // здесь await использовать нельзя
  }
  catch (Exception e)
  {
    Console.WriteLine("TestVoid error: {0}", e);
  }
  Console.WriteLine("done");
}

static async void TestVoid()
{
  await Task.Yield();
  throw new ApplicationException("TestVoid");
}

static async Task TestTask()
{
  await Task.Yield();
  throw new ApplicationException("TestVoid");
}


Running TestTask
TestTask error: System.ApplicationException: TestVoid
at test2.Program.<TestTask>d__2.MoveNext() in D:\Projects\.Net\_tests\test2\test2\Program.cs:line 54
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at test2.Program.<Main>d__0.MoveNext() in D:\Projects\.Net\_tests\test2\test2\Program.cs:line 26
Running TestVoid
done
UnhandledException: System.ApplicationException: TestVoid
at test2.Program.<TestVoid>d__1.MoveNext() in D:\Projects\.Net\_tests\test2\test2\Program.cs:line 48
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback,
Object state, Boolean preserveSyncCtx
)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback,
Object state, Boolean preserveSyncCtx)
at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
at System.Threading.ThreadPoolWorkQueue.Dispatch()

Unhandled Exception: System.ApplicationException: TestVoid
at test2.Program.<TestVoid>d__1.MoveNext() in D:\Projects\.Net\_tests\test2\test2\Program.cs:line 48
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback,
Object state, Boolean preserveSyncCtx
)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback,
Object state, Boolean preserveSyncCtx)
at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
9 апр 21, 10:25    [22306315]     Ответить | Цитировать Сообщить модератору
 Re: От чего может виснуть этот код?  [new]
Сон Веры Павловны
Member

Откуда:
Сообщений: 6192
hVostt
за пределами WinForms события лучше не использовать.
и вообще забыть про них как про страшный сон.

Интересно, как это можно реализовать, например, в случае SqlConnection.InfoMessage (таких примеров можно привести много)
9 апр 21, 10:31    [22306319]     Ответить | Цитировать Сообщить модератору
 Re: От чего может виснуть этот код?  [new]
hVostt
Member

Откуда:
Сообщений: 19318
Сон Веры Павловны
Интересно, как это можно реализовать, например, в случае SqlConnection.InfoMessage (таких примеров можно привести много)


Согласен, есть легаси контракты, которые до сих пор поддерживаются.
От этих эвентов нужно максимально абстрагироваться и декорировать.
9 апр 21, 10:56    [22306328]     Ответить | Цитировать Сообщить модератору
 Re: От чего может виснуть этот код?  [new]
Бариску Нацарство
Member

Откуда:
Сообщений: 11
hVostt
Бариску Нацарство
Джон Скит из МС утверждает везде что на каждом асинхронном вызове должен висеть .ConfigureAwait(false).
Вы утверждаете, что это делает вызов синхронным. И кому верить?


ничего он такого не утверждает.


Он именно так и утверждает в каждом из его 1000ч постов, которые он плодит на стэкэксчендже и в каждом ссылается на свои блог посты. Везде одно и то же: вешайте .ConfigureAwait(false) на каждый await чтобы не было дедлоков.
9 апр 21, 14:21    [22306469]     Ответить | Цитировать Сообщить модератору
 Re: От чего может виснуть этот код?  [new]
Бариску Нацарство
Member

Откуда:
Сообщений: 11
Shocker.Pro
А не проще ли взять учебник и прочесть

А какой учебник?

Я 5 лет работал в компании, где, в соответствии утверждениям Скита, .ConfigureAwait(false) висел на каждом await, и мои пулл реквесты не одобряли, пока я не добавлял их. Объяснить, зачем они это требуют, правда тоже не могли.
9 апр 21, 14:24    [22306473]     Ответить | Цитировать Сообщить модератору
 Re: От чего может виснуть этот код?  [new]
fkthat
Member

Откуда:
Сообщений: 4880
Бариску Нацарство
Везде одно и то же: вешайте .ConfigureAwait(false) на каждый await чтобы не было дедлоков.

Блин, а просто самому прочтитать доки о том, что делает .ConfigureAwait(...) сложно, что ли?
9 апр 21, 14:47    [22306500]     Ответить | Цитировать Сообщить модератору
 Re: От чего может виснуть этот код?  [new]
Бариску Нацарство
Member

Откуда:
Сообщений: 11
fkthat
Бариску Нацарство
Везде одно и то же: вешайте .ConfigureAwait(false) на каждый await чтобы не было дедлоков.

Блин, а просто самому прочтитать доки о том, что делает .ConfigureAwait(...) сложно, что ли?


Configures the awaiter to await this Task<TResult>.

true to attempt to marshal the continuation back to the original context captured; otherwise, false.

И что это мне должно сказать?

Сообщение было отредактировано: 9 апр 21, 17:33
9 апр 21, 17:40    [22306634]     Ответить | Цитировать Сообщить модератору
 Re: От чего может виснуть этот код?  [new]
felix_ff
Member

Откуда: Moscow
Сообщений: 1780
Бариску Нацарство,

https://devblogs.microsoft.com/dotnet/configureawait-faq/
9 апр 21, 18:06    [22306659]     Ответить | Цитировать Сообщить модератору
 Re: От чего может виснуть этот код?  [new]
Бариску Нацарство
Member

Откуда:
Сообщений: 11
felix_ff
Бариску Нацарство,

https://devblogs.microsoft.com/dotnet/configureawait-faq/


много пиндосских букв. моего мозга не хватает чтобы всё это постичь. так нужен конфигюр или не нужен?

Сообщение было отредактировано: 9 апр 21, 18:23
9 апр 21, 18:21    [22306662]     Ответить | Цитировать Сообщить модератору
 Re: От чего может виснуть этот код?  [new]
Бариску Нацарство
Member

Откуда:
Сообщений: 11
petalvik
Бариску Нацарство,

Вот этот код ошибочен:

Правильный код:

[src c#]
private async void Form1_LoadAsync(object sender, EventArgs e)
{
    await LoadSomeEntities1();
    await LoadSomeEntities2();
    await LoadSomeEntities3();
}



Почему даже после этого методы Load...() исполняются последовательно?
В логах видно, что каждый следующий стартует только после окончания предыдущего. Разве они не должны стартовать одновременно и заканчиваться, как успеют?
9 апр 21, 18:34    [22306668]     Ответить | Цитировать Сообщить модератору
 Re: От чего может виснуть этот код?  [new]
fkthat
Member

Откуда:
Сообщений: 4880
Бариску Нацарство
Почему даже после этого методы Load...() исполняются последовательно?

ОМГ, а как же они еще должны выполняться по-твоему, если перед каждым стоит await?

Я еще раз говорю - погугль, почитай доки и т.п. чтобы разобраться для чего вообще ConfigureAwait нужен.
+
подсказка - можешь сразу просто гуглить что такое synchronization context
9 апр 21, 19:28    [22306707]     Ответить | Цитировать Сообщить модератору
 Re: От чего может виснуть этот код?  [new]
hVostt
Member

Откуда:
Сообщений: 19318
Бариску Нацарство
много пиндосских букв. моего мозга не хватает чтобы всё это постичь. так нужен конфигюр или не нужен?


Не нужен.
9 апр 21, 19:56    [22306730]     Ответить | Цитировать Сообщить модератору
 Re: От чего может виснуть этот код?  [new]
fkthat
Member

Откуда:
Сообщений: 4880
hVostt
Не нужен.

Вообще-то нужен когда х/з что и как будет твой код вызывать. Линтеры так-то на его отсутствие ворчат. Я обычно просто из-за этого пишу, хотя лично мне-то он как раз вообще пофиг, т.к. работаю только с ASP.NET Core.
9 апр 21, 20:05    [22306736]     Ответить | Цитировать Сообщить модератору
 Re: От чего может виснуть этот код?  [new]
Shocker.Pro
Member

Откуда: ->|<- :адуктО
Сообщений: 22381
Бариску Нацарство
так нужен конфигюр или не нужен?
Блин, зависит от способа использования. В случае неиспользования в одном случае - дедлок, в случае использования - в другом случае - проблемы с контекстом синхронизации. Как это объяснить в двух словах, если ты за пять лет не смог в этом разобраться (даже в await)? Не получается учебник на английском - возьми перевод - Троелсен, Албахари и т.п., везде разжевывается многопоточность и с чем ее едят, что такое таски, что такое аваиты и т.п.
Бариску Нацарство
Я 5 лет работал в компании, где, в соответствии утверждениям Скита, .ConfigureAwait(false) висел на каждом await, и мои пулл реквесты не одобряли, пока я не добавлял их.
Ну так может вы писали код там, где не было контекста синхронизации. Ты выдернул проблематику из контекста и пытаешься теперь везде ее пихать, да еще прикрываешь своё незнание ссылкой на авторитеты.
9 апр 21, 21:03    [22306760]     Ответить | Цитировать Сообщить модератору
 Re: От чего может виснуть этот код?  [new]
Бариску Нацарство
Member

Откуда:
Сообщений: 11
fkthat
ОМГ, а как же они еще должны выполняться по-твоему, если перед каждым стоит await?


а зачем тогда нужны эти async и его await, если всё равно как выполнялось синхронно, так и выполняется?
гораздо проще старые, проверенные Task.Run(). Они-то по крайней мере точно выполняются параллельно.
9 апр 21, 21:35    [22306772]     Ответить | Цитировать Сообщить модератору
 Re: От чего может виснуть этот код?  [new]
Shocker.Pro
Member

Откуда: ->|<- :адуктО
Сообщений: 22381
Бариску Нацарство
а зачем тогда нужны эти async и его await, если всё равно как выполнялось синхронно, так и выполняется?
гораздо проще старые, проверенные Task.Run(). Они-то по крайней мере точно выполняются параллельно.
О боже. Знания о многопоточности даже не на уровне юниора.
Будешь читать учебник, заодно посмотри, чем отличается асинхронность от многопоточности.
За книжки бегом!

Сообщение было отредактировано: 9 апр 21, 21:47
9 апр 21, 21:54    [22306776]     Ответить | Цитировать Сообщить модератору
 Re: От чего может виснуть этот код?  [new]
hVostt
Member

Откуда:
Сообщений: 19318
fkthat
hVostt
Не нужен.

Вообще-то нужен когда х/з что и как будет твой код вызывать. Линтеры так-то на его отсутствие ворчат. Я обычно просто из-за этого пишу, хотя лично мне-то он как раз вообще пофиг, т.к. работаю только с ASP.NET Core.


Ток для библиотек. Можно даже Fody настроить, чтобы автоматом добавлял.
9 апр 21, 22:35    [22306795]     Ответить | Цитировать Сообщить модератору
 Re: От чего может виснуть этот код?  [new]
hVostt
Member

Откуда:
Сообщений: 19318
Бариску Нацарство
а зачем тогда нужны эти async и его await, если всё равно как выполнялось синхронно, так и выполняется?
гораздо проще старые, проверенные Task.Run(). Они-то по крайней мере точно выполняются параллельно.


Ну вот и используйте Task.Run().
Главное чтобы вас лично всё устраивало.
9 апр 21, 22:36    [22306796]     Ответить | Цитировать Сообщить модератору
 Re: От чего может виснуть этот код?  [new]
fkthat
Member

Откуда:
Сообщений: 4880
hVostt
Ток для библиотек.

Ну да, я это и имел в виду под "х/з кто будет вызывать".

hVostt
Можно даже Fody настроить, чтобы автоматом добавлял.

Так даже студия это умеет по "Ctrl+точка".
9 апр 21, 22:38    [22306798]     Ответить | Цитировать Сообщить модератору
 Re: От чего может виснуть этот код?  [new]
fkthat
Member

Откуда:
Сообщений: 4880
hVostt
Ну вот и используйте Task.Run().

Судя по тому что пишет автор, представляю что это будет :))
9 апр 21, 22:40    [22306800]     Ответить | Цитировать Сообщить модератору
 Re: От чего может виснуть этот код?  [new]
hVostt
Member

Откуда:
Сообщений: 19318
fkthat
Так даже студия это умеет по "Ctrl+точка".


Fody немного иначе работает, он модифицирует dll, добавляя туда вызовы для каждого await.
9 апр 21, 22:41    [22306801]     Ответить | Цитировать Сообщить модератору
 Re: От чего может виснуть этот код?  [new]
hVostt
Member

Откуда:
Сообщений: 19318
fkthat
hVostt
Ну вот и используйте Task.Run().

Судя по тому что пишет автор, представляю что это будет :))


Будет очередной легаси :)
9 апр 21, 22:51    [22306803]     Ответить | Цитировать Сообщить модератору
 Re: От чего может виснуть этот код?  [new]
Сон Веры Павловны
Member

Откуда:
Сообщений: 6192
fkthat
Бариску Нацарство
Почему даже после этого методы Load...() исполняются последовательно?

ОМГ, а как же они еще должны выполняться по-твоему, если перед каждым стоит await?

Я еще раз говорю - погугль, почитай доки и т.п. чтобы разобраться для чего вообще ConfigureAwait нужен.

Не. Тут сначала нужно читать про то, как вообще await устроен и действует. Налицо факт полного непонимания основных концепций этой фичи.
10 апр 21, 03:46    [22306873]     Ответить | Цитировать Сообщить модератору
 Re: От чего может виснуть этот код?  [new]
petalvik
Member

Откуда:
Сообщений: 712
Бариску Нацарство

private async void Form1_LoadAsync(object sender, EventArgs e)
{
    await LoadSomeEntities1();
    await LoadSomeEntities2();
    await LoadSomeEntities3();
}


Почему даже после этого методы Load...() исполняются последовательно?


Потому что перед каждым стоит await.

Так они будут выполняться одновременно:

private async void Form1_LoadAsync(object sender, EventArgs e)
{
    var t1 = LoadSomeEntities1();
    var t2 = LoadSomeEntities2();
    var t3 = LoadSomeEntities3();
    await Task.WhenAll(t1, t2, t3);
}

Но это если они не обращаются к одним и тем же объектам. Конкуррентный доступ, все дела...

Бариску Нацарство

а зачем тогда нужны эти async и его await, если всё равно как выполнялось синхронно, так и выполняется?
гораздо проще старые, проверенные Task.Run(). Они-то по крайней мере точно выполняются параллельно.


Вызов await LoadSomeEntities1(); не подвешивает текущий поток. Например, GUI продолжает отрисовываться и реагировать на действия пользователя.
10 май 21, 08:44    [22320008]     Ответить | Цитировать Сообщить модератору
 Re: От чего может виснуть этот код?  [new]
petalvik
Member

Откуда:
Сообщений: 712
Попробую объяснить простыми словами, зачем всё-таки нужен ConfigureAwait.

Когда мы пишем вот так:

await ReadEntitesFromDB();
// или так
await ReadEntitesFromDB().ConfigureAwait(true);


То перед вызовом этого метода захватывается контекст. А после его окончания выполнение возвращается в этот же контекст. Грубо говоря, в тот же поток.
Но этот поток может быть занят какой-то другой задачей. Например, поток GUI может делать отрисовку в событии Paint. Поэтому может быть существенная задержка - ожидание освобождения потока.

А если мы напишем так:

await ReadEntitesFromDB().ConfigureAwait(false);

То после окончания выполнения метода продолжение может быть сделано в любом свободном на этот момент потоке.
Поэтому использование ConfigureAwait(false) в целом ускоряет выполнение, устраняя лишние ожидания.

Поэтому в библиотечном коде рекомендуется практически всегда использовать именно false.

Однако в коде приложения не всегда можно продолжить выполнение в другом потоке.
В частности, если нужно обратиться к контролам формы (TreeView). Обращаться к ним можно только из того потока, в котором они были созданы. Поэтому без ConfigureAwait(false) придётся использовать Invoke. А с ним этого не нужно - мы гарантированно вернулись в нужный поток.
10 май 21, 08:55    [22320011]     Ответить | Цитировать Сообщить модератору
 Re: От чего может виснуть этот код?  [new]
Roman Mejtes
Member

Откуда: г. Пермь
Сообщений: 4206
дело не в потоках, а контексте выполнения/синхронизации, забудь слово потоки

Сообщение было отредактировано: 10 май 21, 10:40
10 май 21, 10:48    [22320043]     Ответить | Цитировать Сообщить модератору
 Re: От чего может виснуть этот код?  [new]
petalvik
Member

Откуда:
Сообщений: 712
Roman Mejtes
дело не в потоках, а контексте выполнения/синхронизации, забудь слово потоки


Наоборот. Всё дело в потоках.
Консольные приложения никогда не имели контекста синхронизации. В ASP.NET Core SynchronizationContext тоже выпилили. Так куда возвращается выполнение после завершения асинхронного кода?
11 май 21, 15:58    [22320521]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: 1 2      [все]
Все форумы / WinForms, .Net Framework Ответить