Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
Предположим у вас есть два потока, t1 и t2. И t1 исполняет некоторую работу, и в какой-то момент желает передать выполнение кода потоку t2.
Вы async/await в консольном приложении не сможете пользоваться не создав msg loop и syncContext.
async/await, и предоставить компилятору и BCL думать о синхронизации и циклах. Повышение уровня абстракции.Is it a problem then that using async like this in a console app might end up running continuations on ThreadPool threads? I can’t answer that, because the answer is entirely up to what kind of semantics you need in your application. For many applications, this will be perfectly reasonable behavior.
async/await, не используя никакой контекст синхронизации?await, проставлено «работать без синхронизации»)Получить race condition становится элементарно
Скорее всего будет работать неочевидно некорректно.
async Do()
{
await Part1();
await Part2();
await Part3();
await Part4();
await Part5();
}
class Program
{
private static List<object> list = new List<object>();
static void Main(string[] args)
{
Run1();
Run2();
Console.ReadLine();
}
private static async void Run2()
{
while (true)
{
await Task.Yield();
list.Add(new object());
}
}
private static async void Run1()
{
while (true)
{
await Task.Yield();
foreach (var l in list)
{
}
}
}
}
async Task и .Wait() на каждом вызове. Вы хотите, чтобы они выполнялись параллельно? Все равно нужно синхронизировать доступ к list.async void — это вещь, которой надо очень сильно избегать.ConfigureAwait(false) в максимально возможном числе мест — она не просто так появилась, контекст влечет за собой накладные расходы (а иногда — и дедлоки).Вы async/await в консольном приложении не сможете пользоваться не создав msg loop и syncContext.Это с какой стати? Если отсутствует текущий контекст синхронизации, continuation будет вызвано в потоке из пула. Другое дело, что к тому моменту может завершиться главный поток вместе со всем приложением, но к работоспособности async/await это не имеет ни малейшего отношения.
А какие у него, собственно, альтернативы, позволяющие запускать фоновые задачи?
До тех пор, пока в требованиях к приложению не значится совместимость со вторым фреймворком.
Тредпул? Автономный тред с очередью задач?И как же тредпул решает проблему возвращения в поток UI после выполнения фоновой задачи? Уйти в фоновой поток действительно просто, я же перечислял способы отобразить результат вычислений на форме.
И как же тредпул решает проблему возвращения в поток UI после выполнения фоновой задачи?
Уйти в фоновой поток действительно просто, я же перечислял способы отобразить результат вычислений на форме.
До тех пор, пока в требованиях к приложению не значится совместимость со вторым фреймворком.У меня всё работает, что я делаю не так?
IAsyncStateMachine, и никаких намеков, что он будет нужен. Если бы библиотека делалась изначально под 2010ю студию (как аналогичная моя) — то в 2012й студии код упал бы с ошибкой компиляции из-за ненайденного интерфейса и нескольких методов.IAsyncMethodBuilder и его метода PreBoxInitialization в билдерах. Видимо, компилятор несколько умнее, чем мне думалось…В .NET я нашел два класса реализующих контекст синхронизации для пользовательского интерфейса, один для WinForms и один для WPF.
// Suppose we are on a UI thread in a Windows Forms / WPF application:
_uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
Task.Run (() => Foo())
.ContinueWith (ant => lblResult.Content = ant.Result, _uiScheduler);await Task.Delay(TimeSpan.FromTicks(9999));
await Task.Delay(TimeSpan.FromTicks(10000));И первое впечатление от найденных статей по контексту синхронизации, это то что нужно. Но после более детального изучения стало понятно что SynchronizationContext появился и развивался в рамках задачи взаимодействия с UI, и этими задачи его использование и ограничивается. Собственно в самом FCL всего два класса от него наследуются, один для WPF и второй для WinForms.
// Register marshaller for background tasks. At this point,
// need to be able to successfully get the handle to the
// parking window. Only do it when we're entering the first
// message loop for this thread.
if (messageLoopCount == 1) {
WindowsFormsSynchronizationContext.InstallIfNeeded();
}
SynchronizationContext — когда MSDN подводит