穿线&调用问题 [英] Threading & Invoke Question

查看:121
本文介绍了穿线&调用问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好

我正在为我的TCP服务器编写客户端代码.我有一个ServerConnection类在其自己的线程中运行,然后有一个线程池,该线程池用于处理和处理独立于接收方的原始信息.

当将单个数据包与原始数据隔离开时,我必须触发一个事件,以便对此感兴趣的程序部分可以为其注册. (打开的每个表单都将传递ServerConnection对象的引用)

现在很明显,如果我尝试在这些事件中使用UI,我会遇到跨线程操作错误...因此,在这里调用我们来

我的问题是:
这甚至可能是一个愚蠢的问题,但是什么都没做
我是否可以通过某种方式事先调用事件...例如,当事件以窗体形式触发时,它已在UI线程中全部就绪,因此我可以直接从那里使用它.

我讨厌在WinForms代码之间必须有一百万次调用和委托.

谢谢:)

Hey guys

I''m working on the client code for my TCP server. I have the ServerConnection class running in its own thread and then I have a thread pool that sits and processes the raw info seperate to the receiving.

When a single packet is isolated from the raw stuff, I have to trigger an event so the parts of the program that are interested in knowing about this can register for it. (Each form that opens will get passed a reference of the ServerConnection object)

Now obviously if I try to work with the UI in these said events I''ll get a cross thread operation error... So Invoke here we come

My question is this:
It might even be a stupid question but here goes nothing
Is there some way I Invoke the event before hand... As in, when the event is triggered in the form, its all ready in the UI thread so I can work with it directly from there.

I''d hate to have to have a million invoke calls and delegates inbetween my WinForms code.

Thanks :)

推荐答案

我将使用System.Threading.SynchronizationContext而不是Invoke.

SynchronizationContext.Current从您的Form1_Load传递到您的ServerConnection,并将其保存为静态内容.

然后,当您想引发一个事件时,编写如下内容:
I would use System.Threading.SynchronizationContext instead of Invoke.

Pass SynchronizationContext.Current from your Form1_Load to your ServerConnection and save it as a static.

Then when you want to raise an event, write something like this:
_sUIContext.Post( o => Event( this, EventArgs.Empty ), null );


并且该事件将在UI线程上引发.

注意,我还没有检查Event != null.我在声明事件时使用了这个技巧(因为有人争论其他模式是否是线程安全的):


and the event will be raised on the UI thread.

Notice I haven''t checked if Event != null. I use this trick when declaring an event ( as there is debate over whether other patterns are thread-safe ):

public EventHandler Event = delegate { };



这会将一个空的委托添加到调用列表,这意味着Event永远不会为null.

尼克



This adds an empty delegate to the invocation list, which means the Event is never null.

Nick


如果我对您的理解正确,我认为这是不可能的.

但是,您可以稍微简化调用.

在事件处理程序中,您可以简单地检查是否需要调用,是否需要调用具有事件处理程序方法作为其方法的委托.
K听起来令人困惑; P

这是一些代码(在vb.net中,但我确定您可以将其转换为c#)

If I understand you correctly I don''t think it''s possible.

You can however simplify the invoke a bit.

In the event handler you can simply check if a invoke is needed and if so call a delegate that has the event handler method as it''s method.
K that sounds confusing ;P

Here is some code (in vb.net but I''m sure you can translate it into c#)

Private Sub event_method(ByVal Param1 As SAPbouiCOM.Application, ByVal param2 As SAPbobsCOM.Company) Handles event
        If Me.InvokeRequired = True Then
            Me.Invoke(New delegate(AddressOf event_method), param1, param2)
        Else
           ''do the code here
        End If
    End Sub



不确定这是否是您要寻找的东西.



Not sure if this is what your looking for tho.


如果您正在使用线程池,并且希望某些东西发生在GUI线程上,那么必须Invoke在某处.

您可以使用 ISynchronizeInvoke [ SynchronizingObject [
If you''re using a thread pool and you want certain stuff to happen on the GUI thread then there''ll have to be Invokes somewhere.

You can use the ISynchronizeInvoke[^] class to handle this internally in the ServerConnection object if you don''t want it in you GUI class.

An example of how this is used is the System.Timers.Timer class. It has a SynchronizingObject[^] property; if you set that to a value (like a reference to your GUI) then the Timer will execute the callback on that object''s thread, otherwise if it''s null then the Timer callback is executed in the Thread Pool. You can create the same behavior in your objects using the ISynchronizeInvoke class.


这篇关于穿线&调用问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆