0

メールが送信されているスレッドを実行しています。スレッドが実行を完了したことをどのように知ることができますか?

new Thread(x => SendMail(node.Attributes["id"].Value.ToString(), node["fname"].InnerText +      " " + node["lname"].InnerText, 500, node["email"].InnerText)).Start();
4

5 に答える 5

3
var thr = new Thread(x => SendMail(node.Attributes["id"].Value.ToString(), node["fname"].InnerText +      " " + node["lname"].InnerText, 500, node["email"].InnerText));
thr.Start();
thr.Join();//In this place main thread will wait
于 2013-01-11T13:09:48.227 に答える
2

作成したスレッドインスタンスへの参照を保持してから、を確認する必要がありThreadStateます。プロパティをチェックしてIsAlive、スレッドが現在実行されているかどうかを確認することもできます。

于 2013-01-11T13:07:13.770 に答える
2

もう 1 つのバリエーションは、ThreadPool.QueueUserWorkItemを と組み合わせて使用​​することManualResetEventです。

そのような:

private void DoWork()
{
    List<ManualResetEvent> events = new List<ManualResetEvent>();

    //in case you need to loop through multiple email addresses 
    //use the foreach here, assuming that the items is a list.

    //foreach(var item in items)
    //{
    var resetEvent = new ManualResetEvent(false);
    ThreadPool.QueueUserWorkItem(arg =>
    {
        SendMail(node.Attributes["id"].Value.ToString(), 
           node["fname"].InnerText + " " + node["lname"].InnerText,
           500, node["email"].InnerText);
        resetEvent.Set();
    });
    events.Add(resetEvent);

    //} <- closes the foreach loop

    //WaitHandle.WaitAll waits for all the threads to finish.
    WaitHandle.WaitAll(events.ToArray());
    MessageBox.Show("Mails are sent", "Notification");
}

これは、メールアドレスのリストまたは配列をループして、各メールのスレッドを個別に開始する場合に特に便利です。

あなたの場合、メールが送信されるのを待っている間に他のことをしたい場合。上記のコードをバックグラウンド スレッドで実行するだけで、メッセージが表示されたら作業が完了したことがわかります。

public void StartMailThread()
{
    Thread myThread = new Thread(DoWork)
    {
        IsBackground = true,
        Name = "MailThread"
    };
    myThread.Start();
}

ただし、スレッドを使用してスレッドプールを開始することは、私には少し奇妙に思えます。

于 2013-01-11T13:20:11.837 に答える
2

それはあなたの環境が何であるかに依存します。たとえば、タスクを使用して継続をサブスクライブすることにより、すべてのスレッドを回避できます。

例えば

var task = Task.Run(DoSomething)
               .ContinueWith(a => Whatever())

または、C# 5 で指定された便利なキーワードを使用して:

var task = await Task.Run(DoSomething);
Whatever();

スレッドを使用する必要がある場合は、デリゲートを渡すことをお勧めします。電子メールが終了したら、それを呼び出すだけです。

// Outside the thread
private Action callback;

// Before starting the thread
callback = MyMethod/*Or a lambda if you want*/;

// In the thread action
Action<object> threadBody = x => 
{
    SendMail(node.Attributes["id"].Value.ToString(), node["fname"].InnerText +      " " + node["lname"].InnerText, 500, node["email"].InnerText);
    callback();
};
于 2013-01-11T13:13:17.560 に答える
1

アンドリューの回答のほかに、BackgroundWorker を使用できます。すでに RunWorkerCompleted イベント BackgroundWorkerがあります。

于 2013-01-11T20:18:18.103 に答える