0

私のC#Windowsアプリケーションでは、SMTP設定を使用してアプリケーションで設定した主要なイベントについてユーザーに通知する自動メールシステムを1つ構築しました...このメールシステムは正常に動作しています。これを実現するために System.Net.Mail 名前空間を使用しました....

私の問題は、メールが正常に送信されるたびに、受信者の名前とその電子メール ID を 1 つの Windows フォームに表示する通知ウィンドウ (ポップアップ ウィンドウ) を表示する必要があることです。

この目的のために、私はセカンダリ スレッドを使用していますが、正しく動作していません。すべてのユーザーにメールを配信するまで、メイン アプリケーションが応答しなくなります。メールごとに 5 秒のスレッド スリープが与えられているため、メールが 10 件あると考えてください。その後、メイン アプリケーションを 50 秒間使用できなくなります。

私は次のような C# コーディングを行いました。

    //My main Function
    public void SendMail(dataset ds)
    {
      for(inti=0;i<ds.Tables[0].Rows.Count;i++)
      {
       string resValue = genFunc.SMTPClienTSetting(ds, mail);
        if (resValue == "True")
        {
            Thread tPopUp = new Thread(new ThreadStart(this.ShowMessagePopUp));
            tPopUp.IsBackground = true;
            tPopUp.Start();
            lblPOpUpInfo = "Message sent successfully";
        }
        else
        {
            Thread tPopUp = new Thread(new ThreadStart(this.ShowMessagePopUp));
            tPopUp.IsBackground = true;
            tPopUp.Start();
            lblPOpUpInfo = "Message sending failed";
        }
       }
    }

    //Thread Function to open secondary form
    public void ShowMessagePopUp()
    {
        try
        {
            frmHomePopUp homePopUp = new frmHomePopUp();
            homePopUp.Show();
            homePopUp.lblInfo.Text = lblPOpUpInfo;
            Application.DoEvents();
            Thread.Sleep(5000);
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

public string SMTPClienTSetting(DataSet ds, MailMessage MailstoSend)
        {
            try
            {
                SmtpClient objsmtp = new SmtpClient();
                NetworkCredential NetAccess = new NetworkCredential();

                NetAccess.UserName = ds.Tables[0].Rows[0][0].ToString();
                NetAccess.Password = ds.Tables[0].Rows[0][1].ToString();
                objsmtp.Credentials = NetAccess;
                objsmtp.Host = ds.Tables[0].Rows[0][2].ToString();
                objsmtp.Port = Convert.ToInt16(ds.Tables[0].Rows[0][3].ToString());

                objsmtp.Send(MailstoSend);

                System.Threading.Thread.Sleep(500);

                return "True";
            }
            catch (NullReferenceException nr)
            {
                return nr.Message;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

スレッドを使用してフォームを表示できますが、メールの送信が完了するまでメインアプリケーションが応答しません....

4

3 に答える 3

2

TPL非同期メール送信およびContinueWithUIスレッドとの対話に使用できます。そんな感じ

for (int i = 0; i < 10; i++)
{
    var asyncTask = Task.Factory.StartNew(() => SendMail(i)).ContinueWith((result) =>
    {
        // UI interaction logic
    });
}
private bool SendMail(string data)
{
    // send logic
    // you can handle result from this function in ContinueWith delegate function
}
于 2013-01-02T12:34:51.813 に答える
0

ここでは新しいスレッドの必要性はわかりません。また、DoEventsの使用は避けてください。ここを参照するか、自分で検索してください。ある種のコンソール/ログとして小さなリストボックスを作成し、そこに成功または失敗のメッセージを表示することを検討しましたか?すべてのユーザーは、メッセージボックスを常に投げかけるアプリケーションを嫌います。

于 2013-01-02T12:29:57.260 に答える
0

ブロッキングコードは実際にはSMTPClienTSettingメソッドに含まれており、この場合、メインスレッド(UIスレッド)で実行されます。UIのブロックを回避するには、このメソッドを別のスレッドで実行する必要があります(Vadimが提案するアプローチを使用できます)。

于 2013-01-02T13:34:54.230 に答える