1

我有一个带 Socket 的类,监听客户端接收数据。当接收到新数据时,我想调用一个事件(如果已实现),但正如您所知,每个连接都有自己的线程,因此事件将在该线程上运行,而您知道其余的。您不能使用表单控件。我如何调用事件(或调用它)。我对线程和网络编程真的很陌生,所以我很欣赏任何例子。

public class HVremotechooser
{
    public delegate void NewOrder(Order order);
    public event NewOrder nOrder;

    //... (code elided)


    public void ReceiveCallback(IAsyncResult AsyncCall)  // new connection of client
    {

         //... (code elided)
         if (nOrder != null)
              nOrder(Order);   // calling the event "nOrder"
         //... (code elided)

    }

}

谢谢你。

4

4 回答 4

1

如果要从非 UI 线程更新表单,则必须调用该操作。我通常做的是以下几点:

private void LongRunningBackgroundThread() {
   // lots of work
   ...
   // Update my form
   InvokeIfRequired(() => {
       ...update form...
   }
}

private static void InvokeIfRequired(Action a) {
    if (control.InvokeRequired) {
        control.Invoke(a);
    } else {
        a();
    }
}

这里这里

于 2012-04-11T13:09:55.050 回答
0

我在上周开发的 Silverlight 应用程序中遇到了类似的问题,并使用了 Dispatcher.BeginInvoke 方法。使用 Windows 表单,使用 Control.BeginInvoke 可能更容易(尽管我相信两者都应该工作):http: //msdn.microsoft.com/en-us/library/system.windows.forms.control .begininvoke.aspx

于 2012-04-11T13:08:55.790 回答
0

您可以使用典型的编组操作,例如将委托InvokeBeginInvoke执行注入到 UI 线程中。ISynchronizeInvoke只需将or的实例传递SynchronizationContext给您的类以促进编组。

但是,在您的情况下,我不会这样做。因为,大概无论如何,这些回调是由于套接字事件而发生的,因此它们很可能会变得艰难而沉重。您绝对不想用所有这些活动来抨击您的 UI 线程。相反,将所有相关数据打包并放入一个集合中,然后 UI 线程可以System.Windows.Forms.Timer在更合理的时间间隔内轮询使用 a。

我一直在撕毁这些编组操作。它们被高估和过度使用。请记住,有两种通用方法可以在 UI 和工作线程之间共享数据和信号。

  • Invoke通过或BeginInvoke在工作线程中推送方法
  • System.Windows.Forms.Timer通过UI 线程中的拉取方法

pull 方法可以而且通常更优雅。

于 2012-04-12T02:43:34.380 回答
0

UI 线程是一个 UI 问题。在我看来,你不应该担心在这段代码中调用 ui 线程。相反,事件的消费者应该做Invoke他们碰巧需要做的或任何其他线程的事情。这样,如果 UI 人员需要更改他们的策略(例如通过使用计时器),您的非 UI 相关代码将不需要更改。

于 2012-04-12T04:26:31.947 回答