Цикл C # (async / await) в задаче блокирует мой основной поток?

#c# #multithreading #asynchronous #async-await

#c# #многопоточность #асинхронный #асинхронное ожидание

Вопрос:

 private async Task<PortalODataContext> CallConnection(Connection connection)
    {
        bool cancel = false;
        connection.Connected = true;
        var task = getConnection(connection);

        while (!cancel amp;amp; !task.IsCompleted)
        {
            Thread.Sleep(100);

            if (connection.Disconected)
            {
                cancel = true;
            }
        }

        return await task;
    }
 

Это моя функция, которую я вызываю в основном потоке следующим образом :

 PortalODataContext portalContext = await this.CallConnection(connectionOpen);
 

Я новичок в async и await, поэтому я просто пытаюсь понять, почему моя задача «CallConnection» блокирует мой основной поток пользовательского интерфейса… ребята , вы можете мне помочь ?

О, и есть getConnection :

 private Task<PortalODataContext> getConnection(Connection connection)
    {            
        return Task.Factory.StartNew(() =>
        {
            try
            {
                var context = connection.ConnectToPortal();
                connection.ListTemplateLib = this.ShellModel.ConnectionManager.GetTemplateLibrarys(connection);
                connection.ListTemplateGrp = this.ShellModel.ConnectionManager.GetTemplateGroups(connection, connection.TemplateLibraryId);
                connection.ListTemplates = this.ShellModel.ConnectionManager.GetTemplates(connection, connection.TemplateGroupId);
                return context;
            }
            catch (Exception)
            {
                throw;
            }
       });
 

Заранее спасибо

Комментарии:

1. Итак, вы хотели бы знать, почему ваш основной поток блокируется?

2. Да, я не могу понять это

3. Похоже, что ваш фактический ввод-вывод по своей сути не является асинхронным, поэтому вы просто создаете синхронизацию по асинхронным методам. Вы действительно не должны этого делать. Если работа по своей сути синхронна, вы должны просто выполнять ее синхронно. Если какому-либо методу более высокого уровня необходимо, скажем, перенести работу в другой поток, чтобы поддерживать отзывчивый поток пользовательского интерфейса, они могут это сделать.

Ответ №1:

Из-за Thread.Sleep

async / await разделите ваш метод на две части, до и после await . В первой половине у вас есть Thread.Sleep , в результате чего вызывающий поток зависает.

Использовать:

 private async Task<PortalODataContext> CallConnection(Connection connection)
{
    bool cancel = false;
    connection.Connected = true;
    var task = getConnection(connection);

    while (!cancel amp;amp; !task.IsCompleted)
    {
        await Task.Delay(100);

        if (connection.Disconected)
        {
            cancel = true;
        }
    }

    return await task;
}
 

Я не совсем уверен, чего вы пытаетесь достичь здесь.

Комментарии:

1. Это верно. Честно говоря, все методы кажутся мне странными 🙂 Может быть, потому, что это всего лишь отрывок.

2. Я пытаюсь отменить задачу, когда нажимаю на кнопку отключения

3. @Cedric Посмотрите на отмену задачи . Однако он должен быть совместным.

Ответ №2:

Когда вы вызываете асинхронную задачу, вам нужно дождаться результата.

Преимущество асинхронных систем заключается в том, что вы можете запускать два процесса в методе, но только внутри этого метода. Прежде чем вы покинете этот блок, оба процесса должны быть снова объединены. Это упрощает запуск различных процессов без необходимости писать делегаты и блокировки для задействованных объектов.

Посмотрите здесь, чтобы увидеть, что происходит в асинхронных методах. Там есть диаграмма, которая может помочь вам прояснить поток.

В вашем коде вам не нужна тройка.Сон. Метод CallConnection ничего не вернет, пока getConnection что-то не вернет. Затем вы можете продолжить работу в своем основном потоке.

Надеюсь, это поможет вам.