1

私のプログラムからの電子メールの送信を遅らせようとしています。UI をインタラクティブに保つために、新しいスレッドを開始し、スレッドで email メソッドを呼び出しました。できます。メールを送信します。ただし、スレッドをスリープさせる方法がわかりません。実際の電子メール メソッドで Thread.sleep() を使用してみましたが、うまくいかないようです。

Thread oThread = new Thread(new ThreadStart(() => { sendEMailThroughOUTLOOK(recipientAddress, subjectLine, finalbody); }));
                oThread.Start();

メール方法..

public void sendEMailThroughOUTLOOK(string recipient, string subject, string body)
    {
        Thread.Sleep(60000);

        try
        {

            // Create the Outlook application.
            Outlook.Application oApp = new Outlook.Application();
            // Create a new mail item.
            Outlook.MailItem oMsg = (Outlook.MailItem)oApp.CreateItem(Outlook.OlItemType.olMailItem);
            // Set HTMLBody. 
            //add the body of the email
            oMsg.Body = body;

            oMsg.Subject = subject;
            // Add a recipient.
            Outlook.Recipients oRecips = (Outlook.Recipients)oMsg.Recipients;
            // Change the recipient in the next line if necessary.
            Outlook.Recipient oRecip = (Outlook.Recipient)oRecips.Add(recipient);
            oRecip.Resolve();
            // Send.
            oMsg.Send();
            // Clean up.
            oRecip = null;
            oRecips = null;
            oMsg = null;
            oApp = null;



        }//end of try block
        catch (Exception ex)
        {
        }//end of catch

        //end of Email Method
    }
4

2 に答える 2

1

あなたが投稿したコードに明らかに問題はありません。ただし、thread.Suspend() は非常に古い API です。これを行うのは安全ではないため、.NET 2.0 以降は非推奨/廃止されています。

静的メソッド Thread.Sleep(N) は、呼び出し元のスレッドを N ミリ秒間中断することが最も確実です。

明確にするために; Thread.Sleep を呼び出すと、呼び出し元のスレッドが中断されるため、コード例では、

public void sendEMailThroughOUTLOOK(string recipient, string subject, string body)
{
    Thread.Sleep(60000);
    ...
}

Thread.Sleep(60000) への呼び出しは、メソッド sendEMailThroughOUTLOOK を実行しているスレッドを中断しています。そして、あなたはそれ自身のスレッドでそのメソッドを呼び出しているように見えるので、次のように;

Thread oThread = new Thread(new ThreadStart(() => { sendEMailThroughOUTLOOK(recipientAddress, subjectLine, finalbody); }));
oThread.Start();

正しいスレッドを中断する必要があります。

このようなことを行う方法はありません。

 Thread t = new Thread();
 t.Start();
 t.Sleep(60000);

実行中のスレッドを開始または強制終了できますが、スリープ/サスペンドすることはできません。前述のとおり、この API はスレッド同期を実装する安全な方法ではないため、推奨されていません ( http://msdn.microsoft.com/en-us/library/system.threading.thread.suspend%28v=vs.71%を参照)。 29.aspxを参照して、これが適切でない理由を説明してください)。

于 2012-10-02T00:51:14.827 に答える
0

あなたはプログラミングに少し慣れていないので、関連するすべての詳細を説明しようとはしませんが、あなたのサンプルで新しいトリックを見せてくれたのはクールだと思ったので、できればお手伝いしたいと思いました.

これはこれをコーディングする唯一の方法ではありませんが、合理的な方法であると断言できます。バックグラウンド ワーカー コンポーネントを使用して、メールの送信中に UI の応答性を維持します。バックグラウンド ワーカーが提供するイベント DoWork および RunWorkerCompleted の使用に注意してください。これらのイベントのセットアップはデザイナーで行われたため、全体を確認できるようにソリューションを圧縮しました(Google ドライブで実行しましたが、公開共有を行うのはこれが初めての試みです。私の場合と同じようにリンクが開きます。[ダウンロード] を選択できる [ファイル] メニューが表示されます)。

内部プライベート クラスを作成し、それをバックグラウンド ワーカーに渡しました。これは、別のスレッドで実行されているコードから UI コンポーネントのデータにアクセスしたくないためです。これは常に問題を引き起こすわけではありませんが、一般的には良い習慣だと思います。また、後でコードをリファクタリングしたい場合に、DoWork から行を取得して、手間をかけずに別の場所に配置するのが簡単になります。

マルチスレッド プログラミングのより一般的な領域については、多面的なテーマであり、すぐに理解する必要はありません。 これは私のお気に入りのチュートリアルです (この本も素晴らしいです)。

using System;
using System.ComponentModel;
using System.Windows.Forms;
using Outlook = Microsoft.Office.Interop.Outlook;

namespace Emailer
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void SendButton_Click(object sender, EventArgs e)
        {
            this.sendEmailBackgroundWorker.RunWorkerAsync(new _Email
            {
                Recipient = this.recipientTextBox.Text,
                Subject = this.subjectTextBox.Text,
                Body = this.emailToSendTextBox.Text
            });
        }

        private class _Email
        {
            public string Body { get; set; }
            public string Subject { get; set; }
            public string Recipient { get; set; }
        }

        private void sendEmailBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            var email = (_Email)e.Argument;

            try
            {
                Outlook.Application oApp = new Outlook.Application();
                Outlook.MailItem oMsg = (Microsoft.Office.Interop.Outlook.MailItem)oApp.CreateItem(Outlook.OlItemType.olMailItem);
                oMsg.Body = email.Body;
                oMsg.Subject = email.Subject;
                Outlook.Recipients oRecips = (Outlook.Recipients)oMsg.Recipients;
                Outlook.Recipient oRecip = (Outlook.Recipient)oRecips.Add(email.Recipient);
                oRecip.Resolve();
                oMsg.Send();
                oRecip = null;
                oRecips = null;
                oMsg = null;
                oApp = null;
            }
            catch (Exception ex)
            {
                e.Result = ex;
            }

            e.Result = true;
        }

        private void sendEmailBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            string message;

            if (e.Result is Exception) 
                message = "Error sending email: " + (e.Result as Exception).Message;
            else if (e.Result is bool && (bool)e.Result)
                message = "Email is sent";
            else 
                throw new Exception("Internal Error: not expecting " + e.Result.GetType().FullName);

            MessageBox.Show(message);
        }
    }
}
于 2012-10-02T01:57:45.803 に答える