[英]BackgroundWorker Still Blocks IHttpHandler
因此,我具有在我的應用程序中創建日歷事件的UI。 創建新事件后,我會為所有用戶(約3,000個)創建通知。 我新花了一段時間,因為我需要為每個用戶寫數據庫來創建他們的通知,所以我創建了一個從BackgroundWorker
繼承的類。 我並不在乎是否創建了通知(我可以,但不是在為最終用戶完成請求的情況下),因此我認為這是一種有效的方法。
但是,當我去實現它時,即使在調用context.Response.End()
, HttpHandler
仍然等待后台工作程序完成。 我調試了線程,並且HttpHandler
和BackgroundWorker
具有不同的線程ID。 我不確定是否以某種方式使HttpHandler
不能返回,或者我是否誤解了BackgroundWorker
類的用途。
class EventHandler : IHttpHandler
{
...
public void ProcessRequest(HttpContext context)
{
...
// I need this to finish before the response ends
CalendarEvent event = CreateCalendarEvent();
List<int> users = GetUsersFromDB();
if(event != null) // The event was created successfully so create the notifications
{
// This may take a while and does not effect the UI on
// client side, so it can run in the background
NotificationBackgroundWorker notificationWorker = new NotificationBackgroundWorker(notification, users);
notificationWorker.RunWorkerAsync();
} else {
...
// Log Error and set status code for response
...
}
...
context.Response.End()
}
...
}
class NotificationBackgroundWorker : BackgroundWorker
{
private Notification notification;
private List<int> users;
public NotificationBackgroundWorker(Notification newNotification, List<int> usersToNotify) : base()
{
this.notification = newNotification;
this.users = usersToNotify;
this.DoWork += DoNotificationWork;
}
private void DoNotificationWork(object sender, DoWorkEventArgs args)
{
CreateUserNotifications(notification, users);
}
private void CreateUserNotifications(Notification notification, List<int> userList)
{
// This is where the bottleneck is occurring because there
// is one DB write per user
foreach (int userId in userList)
{
...
// Create the notification for each user
...
}
}
}
任何見解都會很棒。 預先感謝一堆!
BackgroundWorker
與當前的SynchronizationContext
集成。 它的設計方式是,它不會讓當前請求在BackgroundWorker
完成之前結束。 這是您大多數時候想要的。
我建議您通過啟動一個新Task
來將工作項排隊到線程池中。
在另一個線程中執行此操作,而不要使用BackgroundWorker。 我不確定BackGroudWorker是否可以在這種情況下工作。
public void ProcessRequest(HttpContext context)
{
...
// I need this to finish before the response ends
CalendarEvent event = CreateCalendarEvent();
List<int> users = GetUsersFromDB();
if(event != null) // The event was created successfully so create the notifications
{
Thread thread = new Thread(
() =>
{
CreateUserNotifications(notification, users);
});
thread .IsBackground = true;
thread.Start();
} else {
...
// Log Error and set status code for response
...
}
...
context.Response.End()
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.