0

私はUDPリスナーWindowsアプリケーションに取り組んでいます。UDPメッセージがアプリケーションに到達すると、このudpメッセージに関連するルーチンを実行する新しい専用スレッドを作成します。

このルーチンは非同期的に呼び出されます。

なぜ非同期なのか?

非同期呼び出しはスレッドプールでキューに入れられるため、主にUDPが来る順序を維持するためです(各スレッドを同期させた場合はそうではありません)。

私の質問:

  • このルーチンが子スレッドで実行されている場合でも、ルーチンを非同期で実行することをお勧めしますか?
  • はいの場合、ファイアアンドフォーゲットパターンであっても、この非同期呼び出しにIsBusyの最良の方法を実装しますか?

私が達成したいことをうまく説明していることを願っています

私の悪い英語をお詫びします

よろしく

xPridex

注意:これは正確なコードではありません。私が持っているのは、責任に関する多くの詳細を削除したものです。

/// <summary>
/// Launch SendNotificationToEBSECW treatment.
/// </summary>
/// <param name="sender">object : UDPmsg_t_Mapping</param>
private void StartPrepared(object sender)
{
            mainThread = new Thread(new ParameterizedThreadStart(EntryPointV3));
            mainThread.Start(sender);
}

private readonly object _sync = new object();
private bool _myTaskIsRunning = false;

public bool IsBusy
{
  get { return _myTaskIsRunning; }
}


public void DoWorkAsynch(Tuple.Create(x,y))
{
  MyTaskWorkerDelegate worker = new MyTaskWorkerDelegate(EntryPointV3);
  AsyncCallback completedCallback = new AsyncCallback(MyTaskCompletedCallback);

  lock (_sync)
  {
    if (_myTaskIsRunning)
      throw new InvalidOperationException("currently busy.");

    AsyncOperation async = AsyncOperationManager.CreateOperation(null);
    worker.BeginInvoke(Tuple.Create(x,y), completedCallback, async);
    _myTaskIsRunning = true;
  }
}

private void MyTaskCompletedCallback(IAsyncResult ar)
{
  // get the original worker delegate and the AsyncOperation instance
  MyTaskWorkerDelegate worker =
    (MyTaskWorkerDelegate)((AsyncResult)ar).AsyncDelegate;
  AsyncOperation async = (AsyncOperation)ar.AsyncState;

  // finish the asynchronous operation
  worker.EndInvoke(ar);

  // clear the running task flag
  lock (_sync)
  {
    _myTaskIsRunning = false;
  } 

  // raise the completed event
  AsyncCompletedEventArgs completedArgs = new AsyncCompletedEventArgs(null,
    false, null);
  async.PostOperationCompleted(
    delegate(object e) { OnMyTaskCompleted((AsyncCompletedEventArgs)e); },
    completedArgs);
}

public event AsyncCompletedEventHandler MyTaskCompleted;

protected virtual void OnMyTaskCompleted(AsyncCompletedEventArgs e)
{
  if (MyTaskCompleted != null)
    MyTaskCompleted(this, e);
}
4

1 に答える 1

1

そのコードには明らかに問題はありませんが、いくつかコメントがあります。

  • new Threadスレッドプールを使用せず、常に新しい専用スレッドを作成します。
  • 新しい専用スレッドを作成したり、スレッドプールを使用したりしても、スレッドのスケジューリング、実行された作業、およびその他の制御できないことが原因で、スレッドが正常に完了することは保証されません。

受信した順序でメッセージを処理する必要がある場合は、各メッセージを別々のスレッドで処理しないでください。代わりに、各メッセージをキューに追加し、キュー内の各アイテムをバックグラウンドスレッドで順番に処理します。

スレッドには、完了時に作成者に警告したり、結果を返したりする組み込みの方法はありません。それをしたい場合は、System.MulticastDelegate.BeginInvoke;を使用してください。スレッドプールを使用します。スレッドの実行中に中間結果が必要な場合は、を使用しますBackgroundWorker

于 2012-12-14T18:37:36.183 に答える