Страницы

Поиск по вопросам

суббота, 4 апреля 2020 г.

Задержки при ожидание ответа (Dataflow)

#c_sharp #async_await #tpl_dataflow

                    
В программе необходимо в отдельном потоке проводить некоторые операции, как например
отправлять запрос серверу и ждать от него ответ. Для реализации использую библиотеку
Dataflow, дабы выполнять это всё последовательно. 
Реализовал такой класс:

partial class PoolManager
{
    CancellationTokenSource CT;
    TransformBlock, string> ActionBlock;

    public PoolManager()
    {
        PM = this;
        CT = new CancellationTokenSource();
        ActionBlock = new TransformBlock, string>(async n =>
        {
            await Task.Delay(2000);
            string a = "";
            try
            {
                a =  n();
            }
            catch (Exception e) { }
            return a;
        },
        new ExecutionDataflowBlockOptions { CancellationToken = CT.Token });
    }

    public void Add(Action func, string message)
    {
        ActionBlock.Post(new Func(delegate () { func(); return message; }));
    }
}  


И целом работает как нужно, но когда я посылаю в него функцию, внутри которой есть
отправка и ожидание ответа, то на моменте ожидания, интерфейс программы подвисает.
В среднем это 100мс, иногда доходит и до 500мс или 1000мс, что становится очень заметно.
Не понимаю в чём причина, ибо он в отдельном потоке должен идти.
    


Ответы

Ответ 1



Вопрос решился сам собой. В целом данный код работает вполне корректно, и проблема таилась глубже. В конкретной задаче на которой я тестировал этот код, в TransformBlock отправлялась функция находящаяся в элементе управления UserControl. В этой функции вызывался метод экземпляра класса, и этот метод посылал запрос на сервер и ожидал ответа. Метод был синхронный и потому поток в котором он вызывался должен был блокироваться. Для того, что бы этого не было делал это в паралельном потоке, но основной поток всё равно блокировался. В итоге я обратил внимание, что код в посылаемой функции выполяется через Dispatcher, дабы я мог выполнять заполнение ProgressBar, и следовательно проверив номер потока через Thread.CurrentThread.ManagedThreadId, при входе в функцию и в диспетчер, понял что код внутри Dispatcher выполняется в уже в потоке UI, а не в потоке TransformBlock, от того запрос и проходил в потоке UI, что и вызывало подвисание. Спасибо VladD, за помощь в решении данной проблемы.

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

Отправить комментарий