2011-07-31 1 views
1

私はクライアント用に管理しているサイトを持っており、メンバー全員にメールを送信したいと考えていました。私はホストに連絡し、毎分50分以下のバッチで送信するように書いて、メールサーバーに過負荷がかからないようにすることを提案しました。asp.netでのスレッド

これは、管理者に電子メールを送信して各バッチ間でリロードする際に、管理者にページを表示させてもらうことなく、これを行うことができる唯一の方法です作業を行うスレッドとそのスレッドは、各バッチ後に60秒間スリープするように設定されています。

私のマシンからコードを実行すると、正常に動作し、電子メールのリスト全体が完成します。 ftp以外のWebホストから実行すると、ほぼ完了しますが、そうではありません。その後、送信されなかったものを終了するためにashxページを再度ヒットしようとすると、何もしません。それは、スレッドが何かをロックアップさせ、追加のスレッドが実行されないようにするようなものです。

私は使用しているコードを使用しています。以前はスレッドを使用していませんでした...だから、これをやっている理由と正しく動作させる方法を知っていますか?私は完了した後にスレッドを削除する必要がありますか?もしそうなら、どうですか?ありがとう。

public void ProcessRequest(HttpContext context) 
    { 

     if (context.Request.QueryString["id"].IsValid<int>()) 
     { 
      campaignId = context.Request.QueryString["id"].To<int>(); 
      var t = new Thread(new ThreadStart(SendEmails)) 
         { 
          Priority = ThreadPriority.Lowest 
         }; 
      t.Start(); 
     } 
    } 

    private void SendEmails() 
    { 
     int currentCount = 0; 
     BroadcastEmailCampaign campaign = EmailController.GetCampaign(campaignId, false); 
     List<Member> memberlist = EmailController.GetEmailList(campaign.CampaignId); 

     var message = new MailMessage 
          { 
           Body = campaign.Body, 
           From = new MailAddress(campaign.SentBy), 
           IsBodyHtml = true, 
           Subject = campaign.Subject, 
           BodyEncoding = Encoding.UTF8 
          }; 

     //add attachment 
     if (!string.IsNullOrEmpty(campaign.Attachment) && File.Exists(campaign.Attachment)) 
     { 
      var attachment = new Attachment(campaign.Attachment); 
      EmailAttachmentType.SetContentProperites(campaign.Attachment, ref attachment); 
      message.Attachments.Add(attachment); 
     } 

     if (memberlist.Count <= 0) 
     { 
      return; 
     } 

     bool sendingComplete = false; 
     EmailController.SetCampaignSendingStatus(true, campaign.CampaignId); 

     while (sendingComplete == false) 
     { 
      message.Bcc.Clear(); 
      message.To.Clear(); 

      message.To.Add(new MailAddress(dummyEmailAddress)); 

      List<Member> emailsToSend = memberlist.Skip(currentCount).Take(takeCount).ToList(); 

      if (emailsToSend.Count <= 0) 
      { 
       sendingComplete = true; 
       EmailController.LogEmailCampaignResult(campaign); 
       EmailController.SetCampaignSendingStatus(false, campaign.CampaignId); 

      } 

      if (!sendingComplete) 
      { 
       foreach (Member email in emailsToSend) 
       { 
        message.Bcc.Add(new MailAddress(email.Email)); 
        campaign.SentTo.Add(new BroadcastEmailCampaignSentTo 
              { 
               MemberId = email.MemberId, 
               Email = email.Email, 
               DateSent = DateTime.Now 
              }); 
       } 

       EmailController.SendEmail(message); 
       EmailController.LogEmailsSent(emailsToSend, campaignId); 

       currentCount += takeCount; 

       Thread.Sleep(pauseTime); 
      } 
     } 

    } 

答えて

0

t.IsBackground = true;

もしそうでなければ、ThreadPoolをQueueUserWorkItemと一緒に使うことをお勧めします。

+0

私はそれを試してみましょう。ありがとう! –

1

私はASP.NETで多くのスレッディングを読んでいて、dosとdontsの本当の手掛かりがないので、通常、Windowsタスクスケジューラのスケジュールされたタスクとして実行するコンソールアプリケーションで記述するタスクを解決します。 5分:

  1. ASP.NETページでは、すべての必要な情報をデータベーステーブルに書き込みます。
  2. スケジューラは定期的に新しいジョブ(たとえば電子メールの送信)を処理してデータベーステーブルをポーリングし、キューとして機能するデータベーステーブルを空にします。

これにより、私のアプリケーションは応答性を保つことができ、IISRESETなどのバックグラウンドスレッドを削除する心配もありません。

関連する問題