异步发送事件 [英] sending events asynchronously

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

问题描述



我熟悉c,c ++等,我花了一个星期的时间试着用c#

写我的

第一个应用程序它工作得相当好,但我很难掌握

线程间信令等。


我已经阅读了有关委托,事件处理程序,调用方法的所有内容等等,但是他们似乎都有不可思议的副作用,因为我已经尝试过了。


应用程序中最困难的部分是退出,我猜对了我只能

忽略它,让它失败,让它失败,

但usb蓝牙com设备不太喜欢它,需要很长时间

在它再次打开之前。


我有一个单独的线程,它从com端口读取,并且需要尽可能实时地实现
。 />
它还需要将数据发送到UI。它也可能会在开放,读取等等一段时间内陷入停滞状态,并且UI线程必须在退出应用程序之前等待,如果

它等同于com线程即将使用调用来更新UI它会使b / b得到死锁。

使用BeginInvoke的
在线程池上太重了,因为数据可以

相当快。


将数据放入受锁定保护的列表中即可,

但问题是如何得到UI线程看,

轮询要么太慢还是要花费很多cpu时间,

a辅助线程等待列表变为非空可能然后

使用调用来更新UI

这会起作用但似乎变得相当复杂。


想要我想要的将事件发送到UI的主消息泵

线程将如何完成

的低级语言


我尝试过OnEvent方法,但是他仍然只是在当前线程中运行事件处理程序




c#中是否有一些等价物或我忽略的东西?


谢谢

Colin = ^。^ =

解决方案

On Sun,2007年4月1日12 :12:17 -0700,colin< co ********* @ntworld.NOSPAM.com>

写道:


[...]

idealy我只想将一个事件发送到UI的主要消息泵

线程,它是如何在低级语言


我已经尝试了OnEvent方法,但这仍然只是在当前线程中运行事件

handler。


c#中是否有一些等价物或我忽略的东西?



我刚刚在另一个帖子中发布了类似问题的答案。


基本上,.NET使用术语 ;事件"描述一些非常不同于人们用来编程Windows的东西,而不是事件,

但旧的Win32"事件&还存在。例如,参见

AutoResetEvent类。


恕我直言,这是一个错误的术语事件。因为它使用了
与Win32中预先存在的事件句柄概念冲突,因为

它经常导致人们认为委托/事件处理程序< .NET中的
范例在某种程度上是等价的,实际上它没有任何关系
带有Win32事件句柄的



你可以做所有相同的事件驱动的生产者/消费者的东西在.NET

,你可以在Win32中做。你不需要使用委托/事件处理程序

的东西,事实上可能没有充分的理由。相反,你使用

等待事件对象,其中AutoResetEvent和ManualResetEvent是两个最有可能用于你的目的的类。


Pete


" Peter Duniho" < Np ********* @nnowslpianmk.com在留言中写道

news:op *************** @ petes-computer.local ...


On Sun,2007年4月1日12:12:17 -0700,colin< co ********* @ ntworld.NOSPAM .com>

写道:


> [...]
idealy我只想发送一个事件给UI的主要消息泵
线程是如何在较低级别的语言中完成的

我已经尝试过OnEvent方法但是这仍然只是运行事件
处理程序当前的主题。

c#中是否存在一些与我忽略的东西?



我刚刚在另一个帖子中发布了类似问题的答案。



啊是的我只是读它。


基本上,.NET使用术语事件。描述一些非常不同于人们用来编程Windows的东西,而不是事件,

但旧的Win32"事件&还存在。例如,请参阅

AutoResetEvent类。


恕我直言,这是一个错误的术语事件因为它使用了
与Win32中预先存在的事件句柄概念冲突,因为

它经常导致人们认为委托/事件处理程序< .NET中的
范例在某种程度上是等价的,实际上它与Win32事件句柄无关。




是的我猜他们正试图隐藏旧的不安全的Windows类型事件。


你可以做所有相同的事件驱动的生产者/消费者的东西在.NET

,你可以在Win32中做。你不需要使用委托/事件处理程序

的东西,事实上可能没有充分的理由。相反,你使用

等待事件对象,其中AutoResetEvent和ManualResetEvent是两个最有可能用于你的目的的类。



aha,我也使用AutoResetEvent将com数据传递到数据

处理线程。

但重点是我不想通过等待com

事件来停止UI线程

我认为必须发生这种情况除非我错过了什么

和com线程肯定不想等待来自com端口的其他任何数据,

和我试图避免UI轮询以查看是否有一些数据需要写入UI。


唯一的例外是当程序结束时,它必须等待句柄

关闭之前它可以中止线程,

并且我把它放在OnClosed中但是主窗口仍然是可见的

不可取但我找不到一个更好的地方,它不会让我添加一个

Dispose();


是否有一个线程同步对象将创建一个''事件''

UI任务就像有一个回调

但总是在UI线程上下文?可以在c#

中使用''WindowProc'吗?


到目前为止唯一的选择似乎是另一个线程。


好​​像微软不希望你编写多线程UI应用程序,

结果我到目前为止已经到了accros一些应用程序,所以很明显这样做

所有内容UI线程。

即使调试器在程序没有停止在UI中也是无效的

线程。


谢谢

Colin = ^。^ =


On Sun,2007年4月1日13:22:07 -0700,colin< co **** *****@ntworld.NOSPAM.com>

写道:


是的我猜他们试图隐藏旧的不安全的窗户类型事件。



我不知道你的意思。首先,Win32事件句柄不是
" unsafe"以任何方式。其次,他们并没有隐藏它。他们只需将
包装在.NET Framework类中(实际上是两个类)。这就是他们用Win32所有东西做的


aha,我也使用过AutoResetEvent将数据传递到数据上

继续线程。

但重点是我不想通过等待com

来阻止UI线程我认为必须发生的事件,除非我错过了一些东西



嗯,我想你错过了什么。


首先,我不明白为什么使用BeginInvoke与你的
需求不相容。没有要求你为每一个

i / o操作调用BeginInvoke。我不知道像i / o这样的东西使用BeginInvoke会消耗太多

资源,除非你一次读取一个字节

(和据我所知,在表单上调用BeginInvoke不会使用

线程池线程......它只是在表单上发布调用的消息

队列)。但即使这样,你只需要调用BeginInvoke就可以在你读取一定数量的字节时更新UI,或者当一个

一定数量的时间过去了。


[...]

唯一的例外是当程序结束时,它必须等待

句柄在它可以中止线程之前关闭,



你为什么要中止线程?中止线程是一种非常糟糕的方式

来管理你的线程。


你应该做的只是让应用程序正常退出,并且

包含一些机制,用于指示您为退出而创建的任何非后台线程。通常这将涉及设置某种状态

变量,该变量表示退出,然后执行任何适合于

线程以使其解除阻塞并检查状态变量(例如

设置一个EventWaitHandle实例或关闭一个i / o句柄,比如

Socket)。主线程可以在发出其他

线程的信号后继续并退出,当其他线程完成任何清理它们需要做的b $ b时,整个过程将退出干净利落。


另外,没有理由你不能在Application.Run语句之后关闭表单并将清理代码放在

之后在程序中

模块。


[...]

是否有线程同步对象创建一个''事件''

UI任务就像有一个回调但总是在UI线程上下文中?



是的。这就是BeginInvoke为表单所做的事情。 Invoke和BeginInvoke是

用于必须在表单的线程上执行某些操作的情况。

这是他们处于这种情况的全部目的。 br />


可以在c#中使用''WindowProc'吗?



有很多方法可以在C#中为窗口过程添加功能,但是在这种情况下你应该不需要你这样做吗? 。


[...]

似乎microsoft不希望你编写多线程UI应用程序,


坦率地说,这是一个愚蠢的断言。如果微软不想让你写出多线程的UI应用程序,那么为什么他们会在.NET中为多线程提供如此多的支持呢?




如果有的话,多线程在.NET恕我直言中更容易*。当然,它不是很容易(所有相同的旧同步问题仍然存在),但在

中与许多其他操作系统级别的东西相同已经包含了更多

方便的课程,多线程的东西也是如此。


因此到目前为止我已经开始使用一些应用程序了这显然是在UI线程中的所有内容。

即使调试器在程序没有停留在UI中时也是无效的

线程。



这是真的......我不明白为什么调试器似乎没有好的线程支持

了。我仍然在寻找功能

我习惯使用,当我在调试器中断时,所有线程都停止了,我可以轻松地从一个转向另一个看看

他们停在哪里以及他们的状态是什么。


但破坏的调试器并不是一般阴谋反对的证据

多线程编程,恕我直言。这只是Visual Studio团队

部分失败的证据,以确保新版本的

工具至少包含与以前的版本。


Pete


Hi,
Im familiar with c,c++ etc, and Ive spent a week trying to write my
first app in c#
it works reasonably well, but im having difficulty getting to grips with
inter thread signalling etc.

I have read all about delegates, event handlers, Invoke methods etc, however
they all seem to have undesribale side effects as I have tried them.

The hardest part of the aplication is on exit, well I gues I could just
ignore it and let it fail ungracefully,
but the usb Bluetooth com device doesnt like that very much, it takes ages
before it can be opened again.

I have a seperate thread wich reads from the com port and wich needs to be
as realtime as possible.
it also needs to send data to the UI. it can also get stuck for some time in
the open,read etc, and the UI thread must wait before it exits the app, if
it waits just as the com thread is about to use invoke to update the UI it
gets deadlocked.

using BeginInvoke would be too heavy on the thread pool as the data can be
quite fast.

putting the data in a list protected by lock would be ok,
but then the problem is how to get the UI thread to look,
polling would be either too slow or use up to much cpu time,
a secondary thread to wait for the list to become non empty wich could then
use invoke to update the UI
this would work but seems to be getting rather complicated.

idealy I just want to send an event to the main message pump of the UI
thread wich is how it would be done
in the lower level languages

I have tried the OnEvent method but this still just runs the event handler
in the current thread.

Is there some equavalent in c# or something that I have overlooked ?

thanks
Colin =^.^=

解决方案

On Sun, 01 Apr 2007 12:12:17 -0700, colin <co*********@ntworld.NOSPAM.com>
wrote:

[...]
idealy I just want to send an event to the main message pump of the UI
thread wich is how it would be done in the lower level languages

I have tried the OnEvent method but this still just runs the event
handler in the current thread.

Is there some equavalent in c# or something that I have overlooked ?

I just posted an answer to a similar question in a different thread.

Basically, .NET uses the term "event" to describe something that is very
different from what people used to programming Windows know as an "event",
but the old Win32 "event" still exists. See, for example, the
AutoResetEvent class.

IMHO, it was a mistake for the term "event" to be used given that it
conflicts with the pre-existing notion of event handles in Win32, because
it quite often leads to people thinking that the delegate/event handler
paradigm in .NET is somehow equivalent when in fact it has nothing to do
with Win32 event handles.

You can do all of the same event-driven producer/consumer stuff in .NET
that you can do in Win32. You need not use the delegate/event handler
stuff, and in fact there''s probably no good reason to. Instead you use
waitable event objects, where AutoResetEvent and ManualResetEvent are the
two most likely classes to be useful for your purposes.

Pete


"Peter Duniho" <Np*********@nnowslpianmk.comwrote in message
news:op***************@petes-computer.local...

On Sun, 01 Apr 2007 12:12:17 -0700, colin <co*********@ntworld.NOSPAM.com>
wrote:

>[...]
idealy I just want to send an event to the main message pump of the UI
thread wich is how it would be done in the lower level languages

I have tried the OnEvent method but this still just runs the event
handler in the current thread.

Is there some equavalent in c# or something that I have overlooked ?


I just posted an answer to a similar question in a different thread.

ah yes ive just read it.

Basically, .NET uses the term "event" to describe something that is very
different from what people used to programming Windows know as an "event",
but the old Win32 "event" still exists. See, for example, the
AutoResetEvent class.

IMHO, it was a mistake for the term "event" to be used given that it
conflicts with the pre-existing notion of event handles in Win32, because
it quite often leads to people thinking that the delegate/event handler
paradigm in .NET is somehow equivalent when in fact it has nothing to do
with Win32 event handles.

yes I gues they are trying to hide the old unsafe windows type event.

You can do all of the same event-driven producer/consumer stuff in .NET
that you can do in Win32. You need not use the delegate/event handler
stuff, and in fact there''s probably no good reason to. Instead you use
waitable event objects, where AutoResetEvent and ManualResetEvent are the
two most likely classes to be useful for your purposes.

aha, I have used AutoResetEvent as well to pass com data onto the data
proceesing thread.
but the point is I dont want to stop the UI thread by waiting for the com
event
wich I assume will have to happen unless I have missed something
and the com thread certainly doesnt want to wait for anything other than
data from the com port,
and im trying to avoid the UI polling to see if there is data to be written
to the UI.

The only exeption is when the program ends, it has to wait for the handle to
close before it can abort the thread,
and I have put that in OnClosed but the main window is still visible wich is
undesirable but I couldnt find a better place, it wouldnt let me add a
Dispose();

Is there a thread synchronization object wich will create an ''event'' in the
UI task like having a callback
but always in the UI thread context ? can the ''WindowProc'' be utilised in c#
?

The only alternative so far seems yet another thread.

It seems like microsoft dont want you to write multithreaded UI apps,
as a result ive come accros a few apps so far wich so obviously do
everything in the UI thread.
even the debugger is inefective when the program is stoped not in the UI
thread.

thanks
Colin =^.^=


On Sun, 01 Apr 2007 13:22:07 -0700, colin <co*********@ntworld.NOSPAM.com>
wrote:

yes I gues they are trying to hide the old unsafe windows type event.

I don''t know what you mean by that. First, the Win32 event handle isn''t
"unsafe" by any means. Second, they didn''t "hide" it. They''ve simply
wrapped it in a .NET Framework class (actually, two classes). That''s what
they''ve done with ALL of the Win32 stuff.

aha, I have used AutoResetEvent as well to pass com data onto the data
proceesing thread.
but the point is I dont want to stop the UI thread by waiting for the com
event wich I assume will have to happen unless I have missed something

Well, I think you have missed something.

For one, I don''t see why using BeginInvoke is incompatible with your
needs. There''s no requirement that you call BeginInvoke for every single
i/o operation. I don''t see how something like i/o could consume too many
resources using BeginInvoke, unless you''re reading a single byte at a time
(and as far as I can recall, calling BeginInvoke on a form does not use a
thread pool thread...it just posts the invocation on the form''s message
queue). But even if it would, you could simply only call BeginInvoke to
update the UI when you''ve read a certain number of bytes, or when a
certain amount of time has gone by.

[...]
The only exeption is when the program ends, it has to wait for the
handle to close before it can abort the thread,

Why are you aborting the thread? Aborting a thread is a pretty poor way
to manage your threads.

What you should do is simply allow the application to exit normally, and
include some mechanism for signaling any non-background threads you''ve
created to exit. Usually this would involve setting some sort of state
variable that signals the exit and then doing whatever is appropriate for
the thread to get it to unblock and check the state variable (such as
setting an EventWaitHandle instance or closing an i/o handle like a
Socket). The main thread can go ahead and exit after signaling the other
threads, and when the other threads are done doing whatever cleanup they
need to do, the entire process will exit cleanly.

Alternatively, there''s no reason you can''t just close the form and put
your cleanup code after the Application.Run statement in the Program
module.

[...]
Is there a thread synchronization object wich will create an ''event'' in
the UI task like having a callback but always in the UI thread context ?

Yes. That''s what BeginInvoke does for forms. Invoke and BeginInvoke are
used in situations when something must be executed on the form''s thread.
That''s their whole purpose for being in that situation.

can the ''WindowProc'' be utilised in c# ?

There are ways to add functionality to the window proc in C# but there
should be no need for you to do that in this case.

[...]
It seems like microsoft dont want you to write multithreaded UI apps,

Frankly, that''s a silly assertion. If Microsoft didn''t want you to write
multithreaded UI apps, why in the world would they include so much support
for multithreading in .NET?

If anything, multithreading is *easier* in .NET IMHO. Granted, it''s not a
lot easier (all the same old synchronization issues still exist), but in
the same way that lots of other OS-level stuff has gotten wrapped in more
convenient classes, so too has the multithreading stuff.

as a result ive come accros a few apps so far wich so obviously do
everything in the UI thread.
even the debugger is inefective when the program is stoped not in the UI
thread.

That''s true...I do not understand why the debugger does not appear to have
good thread support any more. I am still looking for the functionality
I''m used to using, where when I break in the debugger, all threads are
stopped and I can easily switch from one thread to another to see where
they are stopped and what their state is.

But the broken debugger isn''t evidence of a general conspiracy against
multithreaded programming, IMHO. It''s just evidence of a failure on the
part of the Visual Studio team to ensure that the new versions of the
tools include at least as much functionality as the previous version.

Pete


这篇关于异步发送事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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