C# 调用在C中的其他线程上实现的事件#

C# 调用在C中的其他线程上实现的事件#,c#,multithreading,events,networking,invoke,C#,Multithreading,Events,Networking,Invoke,我有一个带套接字的类,侦听客户端以接收数据。当接收到新数据时,我想调用一个事件(如果实现了),但正如您所知,每个连接都有自己的线程,因此事件将在该线程上运行,您知道其余的线程。不能使用表单控件。 如何调用事件(或调用它)。我对线程和网络编程非常陌生,所以我很欣赏任何例子 public class HVremotechooser { public delegate void NewOrder(Order order); public event NewOrder nOrder;

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

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)

    }

}

谢谢。

我在上周开发的Silverlight应用程序中遇到了类似的问题,并使用了Dispatcher.BeginInvoke方法。对于Windows窗体,使用Control.BeginInvoke似乎更容易(尽管我认为两者都可以使用):

我上周开发的Silverlight应用程序遇到了类似的问题,并使用了Dispatcher.BeginInvoke方法。对于Windows窗体,使用Control.BeginInvoke似乎更容易(尽管我认为两者都可以):

如果要从非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();
    }
}

请参阅和

如果要从非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();
    }
}

请参阅和

您可以使用典型的marshling操作,如
Invoke
BeginInvoke
将委托的执行注入UI线程。只需将
ISynchronizeInvoke
SynchronizationContext
的实例传递给您的类,以方便封送处理

然而,在你的情况下,我不会这样做。因为,不管怎样,这些回调可能是由于套接字事件而发生的,所以它们很可能是非常严重的。你肯定不想在所有这些活动中猛击你的UI线程。相反,将所有相关数据打包并放入一个集合中,然后UI线程可以使用
System.Windows.Forms.Timer以更合理的间隔轮询该集合

我一直在做这些沼泽作业。它们被高估和过度使用了。请记住,在UI和工作线程之间共享数据和发送信号有两种通用方法

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

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

您可以使用典型的marshling操作,如
Invoke
BeginInvoke
将委托的执行注入UI线程。只需将
ISynchronizeInvoke
SynchronizationContext
的实例传递给您的类,以方便封送处理

然而,在你的情况下,我不会这样做。因为,不管怎样,这些回调可能是由于套接字事件而发生的,所以它们很可能是非常严重的。你肯定不想在所有这些活动中猛击你的UI线程。相反,将所有相关数据打包并放入一个集合中,然后UI线程可以使用
System.Windows.Forms.Timer以更合理的间隔轮询该集合

我一直在做这些沼泽作业。它们被高估和过度使用了。请记住,在UI和工作线程之间共享数据和发送信号有两种通用方法

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

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

UI线程是一个UI问题。在我看来,您不应该担心在这段代码中调用ui线程。相反,事件的使用者应该执行
调用
或其他他们碰巧需要执行的线程操作。这样,如果用户界面人员需要更改策略(例如使用计时器),则不需要更改与用户界面无关的代码。

用户界面线程是一个用户界面问题。在我看来,您不应该担心在这段代码中调用ui线程。相反,事件的使用者应该执行
调用
或其他他们碰巧需要执行的线程操作。这样,如果用户界面人员需要更改他们的策略(例如使用计时器),则不需要更改与用户界面无关的代码。

这是winforms的问题吗?我相信您在问“如何调用ui线程上的调用?”这是winforms问题吗?我相信您会问“如何调用ui线程上的调用?”我知道这一点,但在我的情况下,这是没有用的,因为我编写了一个包含一些事件的组件。使用我的组件的编程人员将实现事件,我不希望他/她关心调用(线程)。我需要调用已实现的事件,以便第三个编程人员轻松完成表单元素的工作。我知道这一点,但在我的情况下,这是没有用的,因为我编写了一个包含一些事件的组件。使用我的组件的编程人员将实现事件,我不希望他/她关心调用(线程)。我需要调用已实现的事件,以便第三个编程人员轻松地使用表单元素完成其工作。