在后台线程中处理事件 [英] Handling events in a background thread

查看:61
本文介绍了在后台线程中处理事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个实例,希望能够处理来自后台线程的事件.具体来说,是为了能够处理由外部硬件(通过串行端口,TCP/IP连接等)生成的事件,以将其数据传递给BackgroundWorker.

I have an instance where I would like to be able to handle events from a background thread. Specifically, to be able to handle events generated by external hardware (via serial port, TCP/IP connection, etc.) to pass their data to the BackgroundWorker.

void Worker_DoWork(object sender, DoWorkEventArgs e)
{
    simpleButton3.Click += new EventHandler(simpleButton3_Click);

    while (!Worker.CancellationPending)
    {
        // Wait for event to be triggered
    }

    simpleButton3.Click -= new EventHandler(simpleButton3_Click);
}

void simpleButton3_Click(object sender, EventArgs e)
{
    // Do something...

    Thread.Sleep(5000);

    // Do something else...
}



但是,在此示例中我发现的是Sleep命令将主(GUI)线程而不是BackgroundWorker置于睡眠状态.

BackgroundWorker线程可以处理事件吗?

谢谢!



However, what I''m finding in this example is that the Sleep command is putting the main (GUI) thread to sleep instead of the BackgroundWorker.

Is it possible for a BackgroundWorker thread to process events?

Thank you!

推荐答案

好吧,对于串行端口和TCP/IP连接,不难从后台工作人员读取/写入数据,并完成大部分处理工作如果您想在用户界面上对结果进行某些操作,请在此处调用ReportProgress.

为了提高效率,您不必过于频繁地使用ReportProgress.如果以百分比报告进度,则通常仅在百分比实际更改时才报告进度,效果相对较好且没有太多开销.

对于打开或关闭串行端口或TCP/IP,可以决定是要在主(UI)线程中还是在后台工作程序中进行.在我的应用程序中,我已经在主线程中做到了.

另外,如果同时进行发送和接收,则取决于您的应用程序,您可能会使用不同的后台工作程序来发送和接收数据.如果我的应用程序将一对用于串行端口,将另一对用于TCP/IP.
Well, for serial ports and TCP/IP connection, it is not hard to read/write data from your background workers an do most of the processing here and call ReportProgress if you want to do something on the UI with the result.

For effeciency, you have to not ReportProgress too often though. If progress is reported in percentage, often reporting the progress only when the percentage actually changes, works relatively well and without too much overhead.

For the opening and closing of the serial port or TCP/IP, you can decide if you want to do it in the main (UI) thread or the background worker. In my application, I have do it in the main thread.

Also, if you do both sending and receiving, depending on your application, you might use distinct background workers for sending and receiving data. If my application I uses a pair of them for serial port and another pair for TCP/IP.


都错了.您为什么认为您在后台线程中向Click事件添加了处理程序?这个不成立.您是否认为如果设法将处理程序添加到某个事件的调用列表中,它将使一个事件本身在同一线程中调用此方法?为什么?没办法!

事件,委托实例和任何方法通常与线程无关.可以从任何线程调用任何方法,但是其效果当然可以不同.

特别是,当您从非UI线程调用任何与UI相关的方法或属性时,就会发生这种情况.你根本做不到.相反,您需要使用System.Threading.DispatcherInvokeBeginInvoke方法(对于Forms或WPF)或System.Windows.Forms.Control(仅对于Forms).

在我过去的答案中,您将找到有关其工作原理的详细说明和代码示例:
Control.Invoke()与Control.BeginInvoke() [ ^ ],
Treeview Scanner和MD5的问题 [如何获取keydown事件在vb.net中的不同线程上操作 [启用禁用+多线程后控件事件不会触发 [ ^ ].

—SA
All wrong. Why do you think you add a handler to a Click event in your background thread? It makes no sense. Do you think if you managed to add a handler to some event''s invocation list, it will make an event itself calling this method in the same thread? Why? No way!

Events, delegate instances and any methods generally have nothing to do with the threads; any method can be called from any thread, but effect of it could be different, of course.

In particular, this is what happens when you call any UI-related methods or properties from non-UI thread. You simply cannot do it. Instead, you need to use the method Invoke or BeginInvoke of System.Threading.Dispatcher (for both Forms or WPF) or System.Windows.Forms.Control (Forms only).

You will find detailed explanation of how it works and code samples in my past answers:
Control.Invoke() vs. Control.BeginInvoke()[^],
Problem with Treeview Scanner And MD5[^].

See also more references on threading:
How to get a keydown event to operate on a different thread in vb.net[^],
Control events not firing after enable disable + multithreading[^].

—SA


这篇关于在后台线程中处理事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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