Если задача заблокирована, она возвращается в очередь или тоже блокирует поток? - PullRequest
0 голосов
/ 06 ноября 2019

Мне было интересно, насколько хороши задачи для сценариев, где основной проблемой является блокировка ресурсов (например, доступ к COM-порту).

Если моя задача такова:

    Task
    {
        lock(resource)
        {
            resource.doSomething();
        }
    };

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

Мой вопрос таков: если ресурс заблокирован, задача возвращается в очередь задач или поток заблокированпока ресурс не освободится?

Насколько я понимаю, если задача заблокирована, в этом случае было бы лучше использовать поток, чтобы избежать заполнения пула потоков заблокированными потоками, верно?

Ответы [ 2 ]

1 голос
/ 06 ноября 2019

Ваше предположение верно. Задача ожидает освобождения ресурса, а затем продолжает его выполнение.
Вы можете определить задачу как LongRunning единицу, поэтому система обрабатывает ее более подходящим образом. Кроме того, вы можете запустить поток, если хотите по какой-либо причине, но учтите, что заблокированный поток не потребляет много ресурсов ЦП, а ThreadPool обрабатывает достаточное количество активных потоков. Если вы не собираетесь выполнять много задач (скажем, более 1000), не беспокойтесь об этом.

0 голосов
/ 06 ноября 2019

Текущая реализация класса System.Threading.ThreadPool при голодании порождает новый поток каждые 500 мсек. Это может создать задержку, если вы используете много потоков пула потоков в режиме блокировки. Однако можно увеличить начальный резерв потоков в ThreadPool, используя метод SetMinThreads. Каждый поток потребляет около 1 МБ памяти, поэтому в этом случае вы будете тратить память на производительность.

int workerThreads, completionPortThreads; // Get the current settings
ThreadPool.GetMinThreads(out workerThreads, out completionPortThreads);
ThreadPool.SetMinThreads(100, completionPortThreads);

Возможно, вы не хотите изменять размер порта завершенияпул потоков (потоки, обрабатывающие завершение запросов ввода-вывода). Таким образом, вы можете получить текущий размер с помощью метода GetMinThreads, а затем использовать его в SetMinThreads для сохранения значения по умолчанию.

...