Вот метод stati c RunLowPriority
, который вы можете использовать вместо Task.Run
. Он имеет перегрузки для простых и общих задач c, а также для обычных и асинхронных делегатов.
const int LOW_PRIORITY_CONCURRENCY_LEVEL = 100;
static TaskScheduler LowPriorityScheduler = new ConcurrentExclusiveSchedulerPair(
TaskScheduler.Default, LOW_PRIORITY_CONCURRENCY_LEVEL).ConcurrentScheduler;
public static Task RunLowPriority(Action action,
CancellationToken cancellationToken = default)
{
return Task.Factory.StartNew(action, cancellationToken,
TaskCreationOptions.DenyChildAttach, LowPriorityScheduler);
}
public static Task RunLowPriority(Func<Task> function,
CancellationToken cancellationToken = default)
{
return Task.Factory.StartNew(function, cancellationToken,
TaskCreationOptions.DenyChildAttach, LowPriorityScheduler).Unwrap();
}
public static Task<TResult> RunLowPriority<TResult>(Func<TResult> function,
CancellationToken cancellationToken = default)
{
return Task.Factory.StartNew(function, cancellationToken,
TaskCreationOptions.DenyChildAttach, LowPriorityScheduler);
}
public static Task<TResult> RunLowPriority<TResult>(Func<Task<TResult>> function,
CancellationToken cancellationToken = default)
{
return Task.Factory.StartNew(function, cancellationToken,
TaskCreationOptions.DenyChildAttach, LowPriorityScheduler).Unwrap();
}
Имейте в виду, что событие Elapsed
для System.Timers.Timer
, которое имеет его свойство SynchronizingObject
, установленное на null
, работает и в потоках ThreadPool
. Поэтому, если вы выполняете работу с низким приоритетом внутри этого обработчика, вам, вероятно, следует запланировать ее через тот же планировщик ограниченного параллелизма:
var timer = new System.Timers.Timer();
timer.Elapsed += (object sender, System.Timers.ElapsedEventArgs e) =>
{
Thread.Sleep(10); // High priority code
var fireAndForget = RunLowPriority(() =>
{
if (!timer.Enabled) return;
Thread.Sleep(1000); // Simulate long running code that has low priority
});
};