0

我正在开发一个 UDP 侦听器 Windows 应用程序,一旦 UDP 消息到达应用程序,我将创建一个新的专用线程,该线程执行与此 udp 消息相关的例程。

该例程被异步调用。

为什么异步?

主要是为了保持 UDP 即将到来的顺序,因为异步调用在线程池中排队(如果我让每个线程同步运行则不是这种情况)。

我的问题:

  • 即使该例程在子线程中运行,异步运行例程也是一个好主意吗?
  • 如果是的话,我是否应该为此异步调用实施 IsBusy 最佳实践,即使它是一种“一劳永逸”的模式?

我希望我能很好地解释我想要实现的目标

为我糟糕的英语道歉

问候

xPridex

注意:这不是准确的代码,我删除了很多关于 lisibity 的细节。

/// <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 回答