gpt4 book ai didi

asp.net - HostingEnvironment.QueueBackgroundWorkItem 使用 ASP.Net 线程池或其他线程池?

转载 作者:行者123 更新时间:2023-12-02 03:57:10 26 4
gpt4 key购买 nike

我有一个 ASP.Net 应用程序,其中使用 HostingEnvironment.QueueBackgroundWorkItem 运行后台任务,如下面的代码所示。

问题:下面代码中安排的后台任务是使用 ASP.Net 线程池线程中的线程,还是使用单独线程池中的线程?

public ActionResult SendCustMails()
{
HostingEnvironment.QueueBackgroundWorkItem(ct => SendCustMailsTo(ct, "Customer Notification"));
return View();
}

private void SendCustMailsTo (CancellationToken ct, string msg)
{
//some code is omitted
foreach (var customer in Customers)
{
if (ct.IsCancellationRequested)
{
break;
}

SendMail(customer, msg);
}

return ct;
}

最佳答案

Hosting environment source code可以看出QueueBackgroundWorkItem 方法使用 _backGroundWorkScheduler 字段(BackgroundWorkScheduler 类型)来调度后台工作项:

public sealed class HostingEnvironment : MarshalByRefObject {
//other field declarations
private static HostingEnvironment _theHostingEnvironment;
private BackgroundWorkScheduler _backgroundWorkScheduler = null; // created on demand
//yet more field declarations


//methods
[SecurityPermission(SecurityAction.LinkDemand, Unrestricted = true)]
public static void QueueBackgroundWorkItem(Action<CancellationToken> workItem) {
if (workItem == null) {
throw new ArgumentNullException("workItem");
}

QueueBackgroundWorkItem(ct => { workItem(ct); return _completedTask; });
}

// See documentation on the other overload for a general API overview.
//
// This overload of QueueBackgroundWorkItem takes a Task-returning callback; the
// work item will be considered finished when the returned Task transitions to a
// terminal state.
[SecurityPermission(SecurityAction.LinkDemand, Unrestricted = true)]
public static void QueueBackgroundWorkItem(Func<CancellationToken, Task> workItem) {
if (workItem == null) {
throw new ArgumentNullException("workItem");
}
if (_theHostingEnvironment == null) {
throw new InvalidOperationException(); // can only be called within an ASP.NET AppDomain
}

_theHostingEnvironment.QueueBackgroundWorkItemInternal(workItem);
}

private void QueueBackgroundWorkItemInternal(Func<CancellationToken, Task> workItem) {
Debug.Assert(workItem != null);

BackgroundWorkScheduler scheduler = Volatile.Read(ref _backgroundWorkScheduler);

// If the scheduler doesn't exist, lazily create it, but only allow one instance to ever be published to the backing field
if (scheduler == null) {
BackgroundWorkScheduler newlyCreatedScheduler = new BackgroundWorkScheduler(UnregisterObject, Misc.WriteUnhandledExceptionToEventLog);
scheduler = Interlocked.CompareExchange(ref _backgroundWorkScheduler, newlyCreatedScheduler, null) ?? newlyCreatedScheduler;
if (scheduler == newlyCreatedScheduler) {
RegisterObject(scheduler); // Only call RegisterObject if we just created the "winning" one
}
}

scheduler.ScheduleWorkItem(workItem);
}
//yet more methods

}

如果我们查看 BackgroundWorkScheduler类的源代码:

internal sealed class BackgroundWorkScheduler : IRegisteredObject {
//....
public void ScheduleWorkItem(Func<CancellationToken, Task> workItem) {
Debug.Assert(workItem != null);

if (_cancellationTokenHelper.IsCancellationRequested) {
return; // we're not going to run this work item
}

// Unsafe* since we want to get rid of Principal and other constructs specific to the current ExecutionContext
ThreadPool.UnsafeQueueUserWorkItem(state => {
lock (this) {
if (_cancellationTokenHelper.IsCancellationRequested) {
return; // we're not going to run this work item
}
else {
_numExecutingWorkItems++;
}
}

RunWorkItemImpl((Func<CancellationToken, Task>)state);
}, workItem);
}
//other methods
}

我们可以注意到它内部使用 Asp.Net ThreadPool 来安排工作项。

关于asp.net - HostingEnvironment.QueueBackgroundWorkItem 使用 ASP.Net 线程池或其他线程池?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31359483/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com