6

TPL機能を導入したい Windows アプリケーションがあります。シナリオは、現在の IMAP 接続 (AE.Net.Mail を使用) だけでなく、s のProcessコレクションが渡されたメソッドを持つクラスを持っていることです。MailMessage

できるだけ多くのスレッドをExecute別のクラスのメソッドにスピンオフして、単一のMailMessageアイテムを取りMailMessage、DB に渡し、IMAP 接続を使用しMailMessageてサーバーから を削除したいと考えています。

プロセスを追跡することについてはあまり心配していません。大量のメールを扱っているので、DB への書き込みや削除でエラーが発生しても心配ありません。できるだけ早く大量の MailMessage を処理するアプリケーションが必要なだけです。

私は遊んでいますTask<MailMessage>.Factory.StartNewが、自分が何をしているのか本当にわかりません。私はそれを開始することができないようです...これが私が試したことです:

Task test = Task.Factory.StartNew(() =>
{
  foreach (var mailMessage in _mms)
  {
    new ProcessMessage().Execute(mailMessage, imapConn);
  }

});

ラムダ式にループを含めるべきではないと確信しています。これを実行すると、 に入らないようですProcessMessage.Execute

4

5 に答える 5

4

lamdba式にループを含めるべきではありません。これを試して:

_mms.ForEach(mms => {
    Task.Factory.StartNew(() => ProcessMessage().Execute(mailMessage, imapConn))
});

結果を追跡する必要がない場合や、Task test = ....などのタスクのインスタンスを保存する必要がない場合は、次の方法を使用して、新しいスレッドでメソッドの実行を開始Task.Factory.StartNew()できます。処理するメールメッセージごとに新しいタスクを開始し、スレッドプールに処理を任せるだけです。

また、Task<MailMessage>.Factory.StartNewMailMessageを返す別のスレッドでメソッド呼び出しを設定するために使用されるため、voidメソッドを呼び出す場合は、これを行う必要はありません。構文はTask<object>常に、新しいタスクで開始するメソッドの戻り型を参照します。

于 2012-12-18T14:00:16.590 に答える
4

現在、foreachループを個別のタスクとして実行していますが、各反復を個別のタスクとして実行することをお勧めします。Parallel.ForEachを試す必要があります。

        Parallel.ForEach(_mms, mailMessage =>
            {
                new ProcessMessage().Execute(mailMessage, imapConn);
            });

これにより、反復が並行して実行されます。これは、あなたがやろうとしていることのようです。

于 2012-12-18T14:03:04.293 に答える
1

これにより、各実行が別々のスレッドで実行されるはずです(つまり、現在何をしているのかがわかります:))

  foreach (var mailMessage in _mms)
  {
     ThreadPool.QueueUserWorkItem(delegate
     {
        new ProcessMessage().Execute(mailMessage, imapConn);
     });
  }

また

  foreach (var mailMessage in _mms)
  {
      new Thread(delegate() { new ProcessMessage().Execute(mailMessage, imapConn); }).Start();
  }
于 2012-12-18T14:00:33.077 に答える
1

これを実行すると、 に入らないようですProcessMessage.Execute

次に、コードに何か問題があるに違いありません。コードは確実に機能するはずです。また、コードを並列化したくない (または並列化できない) 場合は、ラムダでループを使用するのが適切な場合があります。

それを並列化したい場合(質問からは明確ではありません)、たとえば、Parallel.ForEach()これに最適化されたものを使用できます。

于 2012-12-18T15:49:14.803 に答える
1

別のオプションは、コレクション.AsParallel()で andを使用することです。.ForAll()

_mms.AsParallel()
    .ForAll(mm => ProcessMessage().Execute(mm, imapConn));
于 2012-12-18T14:06:24.207 に答える