簡體   English   中英

BackgroundWorker仍然阻止IHttpHandler

[英]BackgroundWorker Still Blocks IHttpHandler

因此,我具有在我的應用程序中創建日歷事件的UI。 創建新事件后,我會為所有用戶(約3,000個)創建通知。 我新花了一段時間,因為我需要為每個用戶寫數據庫來創建他們的通知,所以我創建了一個從BackgroundWorker繼承的類。 我並不在乎是否創建了通知(我可以,但不是在為最終用戶完成請求的情況下),因此我認為這是一種有效的方法。

但是,當我去實現它時,即使在調用context.Response.End()HttpHandler仍然等待后台工作程序完成。 我調試了線程,並且HttpHandlerBackgroundWorker具有不同的線程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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM