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线程上的调用?”我知道这一点,但在我的情况下,这是没有用的,因为我编写了一个包含一些事件的组件。使用我的组件的编程人员将实现事件,我不希望他/她关心调用(线程)。我需要调用已实现的事件,以便第三个编程人员轻松完成表单元素的工作。我知道这一点,但在我的情况下,这是没有用的,因为我编写了一个包含一些事件的组件。使用我的组件的编程人员将实现事件,我不希望他/她关心调用(线程)。我需要调用已实现的事件,以便第三个编程人员轻松地使用表单元素完成其工作。