完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
电子发烧友论坛|
大家好我有一个问题,可能只有VEE人会知道(或Shawn)。我们使用ActiveX UEI框架库。
当获取的数据可用或发生错误时,这会触发事件。我们为此UEI库创建了一个包装器ActiveX DLL,它作为UEI DLL和主机VEE程序之间的层。 VEE轮询包装器库以获得“DataAvailable”状态并从包装器DLL获取数据。奇怪的是,即使主机VEE程序停止(开发模式),UEI框架触发的事件也由我们的包装器DLL处理。 。 我还注意到threadID(API GetCurrentThreadID)在事件处理程序和主机VEE程序中是相同的。 我想这意味着VEE被'中断(即使程序停止)以服务该事件。 这是对的吗?我们看到一些奇怪的错误,我们不确定为什么。 我认为在VEE调用包装器“GetStatus”/“GetData”函数期间,包装器函数被UEI框架触发的事件中断,然后有2个Wrapper DLL函数同时运行访问相同的数据 并导致错误(完成程序锁定)。 Visual Basic应该是“线程安全的”并且应该防止2个函数同时运行,但是VEE可能会改变这个。任何人都可以对这种情况有所了解吗? 当与VEE一起使用时,包装器DLL仍然是“线程安全的”吗?我们正在使用VEE6.03,Visual Basic 6(SP5),WinXP(SP2)感谢任何帮助.Andrew FudgeGenesys Test EngineeringWales, 以上来自于谷歌翻译 以下为原文 Hello all I have a question that may be only the VEE people would know (or Shawn ). We use an ActiveX UEI Framework library. This fires events when acquired data is available or an error occurs. We have created a wrapper ActiveX DLL for this UEI library and it sits as a layer between the UEI DLL and the host VEE program. VEE polls the wrapper library to get a "DataAvailable" status and to get data from the wrapper DLL. The strange thing is that events fired by the UEI Framework are handled by our wrapper DLL even when the host VEE program is stopped (development mode). I also noticed that the thread ID (API GetCurrentThreadID) is the same in the event handler and the host VEE program. I guess this means that VEE is 'interrupted (even when program is stopped) to service the event. Is this right? We are seeing some strange errors and we're not sure why. I think that during a VEE call to a wrapper "GetStatus" / "GetData" function, the wrapper function is interrupted by an event fired by the UEI Framework, and then there are 2 Wrapper DLL functions running at the same time accessing the same data and causing errors (complete program lock-ups). Visual Basic is supposed to be 'thread safe' and should prevent 2 functions running at the same time, but VEE may be changing this. Can anyone shed any light on this scenario? Would the wrapper DLL still be 'thread safe' when used with VEE? We're using VEE6.03, Visual Basic 6 (SP5), WinXP (SP2) Thanks for any help. Andrew FudgeGenesys Test EngineeringWales, UK--- |
|
相关推荐
2个回答
|
|
|
> We have created a wrapper ActiveX DLL
> for this UEI library and it sits as a > layer between the UEI DLL and the host > VEE program. Ok. > The strange thing is that events fired > by the UEI Framework are handled by our > wrapper DLL even when the host VEE program > is stopped (development mode). Expected behavior! Your wrapper subscribes to events published by this library. As long as the library is firing events, your wrapper will receive them. > I also noticed that the thread ID (API > GetCurrentThreadID) is the same in the > event handler and the host VEE program. Yes indeedy (or at least, most probably. This is the default way to do things). When a subscriber subscribes to an event, the actual call the publisher makes (to the COM subsystem) is on the publisher's thread. The call to the subscriber is made on a system thread (COM's) and received on the subscriber's thread. This is the Apartment Threading model. You're seeing the receiver. See: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncomg/html /comthreading.asp > I guess this means that VEE is 'interrupted > (even when program is stopped) to service the > event. Is this right? The call from COM to VEE will most certainly be made. Whether or not VEE does anything with it is VEE's business, but as a matter of fact you are right. For instance, if you subclass VEE's main window (using an event to pass messages up to VEE before returning) and then the VEE program stops, the message processing function will still be called and executed. > I think that during a VEE call to a wrapper > "GetStatus" / "GetData" function, the > wrapper function is interrupted by an event > fired by the UEI Framework, and then there > are 2 Wrapper DLL functions running at the > same time accessing the same data and > causing errors (complete program lock-ups). Weirdness such as this is possible. Personally I think you're right. One thing you can do to diagnose stuff like this is to log function start/stop time along with thread id to a debug window. GetTickCount is good enough. There are definitely different threads involved. If the wrapper data receive starts running before GetData is done, then yup you need a mutex. In general, any time multiple threads are accessing the same buffers, you have to serialize access yourself. This will slow down overall response, but there are ways to get around that. > Visual Basic is supposed to be 'thread > safe' and should prevent 2 functions > running at the same time, but VEE may > be changing this. In effect yes, VEE is changing it. VB is thread safe as long as it doesn't have to deal with multiple threads out of the context of COM (I'm not kidding! I know you'll find claims to the contrary all over the net. The fact is these claims are bogus. Been there, done that, crashed & burned). In VB's own little world it is safe - in the context of COM it is safe, but when you start throwing threads in there from out of the blue, it can't handle it. Try this: create a Win32 thread from Visual Basic with CreateThread. You have just violated VB's supposed thread safety. Nearly anything you do on either thread that calls the CRT will almost certainly crash the VB execution engine. Compiled VB is a bunch of calls to the VB runtime, which are in turn calls to the CRT or Windows API. The problem is that those calls are made through the execution engine and it is not thread safe at all. You get different threads running in there that are not in different apartments and you've got big, big trouble. If your project were all VB, using all COM, then there wouldn't be a problem. > Can anyone shed any light on this > scenario? Would the wrapper DLL still > be 'thread safe' when used with VEE? As long as you're not mixing threads it's cool, but since you are all you have to do is provide your own thread safety and all your problems will go away. Multithreading 101 Think of your wrapper as having an input side and an output side. The events you subscribe to in the original library are those on the input side. The events you publish to VEE are those on the output side. Whatever functions you provide to VEE (like GetStatus & GetData) are on the output side. Likewise, any calls you make as a result of receiving events from the original library are on the input side. Provide a global ghMutex in a module. In Class_Initialize, check to see of the value of ghMutex is 0. If it is, ghMutex = CreateMutex(0&, 0, 0&). Upon entry to *any* input or output function (where resources shared between input and output will be accessed), WaitForSingleObject(ghMutex, -1). At the end of the function (when resource access is over), ReleaseMutex(ghMutex). In Class_Terminate, CloseHandle(ghMutex) and ghMutex = 0. Take care to acquire the mutex only once on either side. For instance, an event arrives, and in the handler you do something like: WaitForSingleObject(ghMutex, -1) status = GetStatusFromEUI() If status And STS_DATA_READY = STS_DATA_READY Then data = GetDataFromEUI() End If ReleaseMutex(ghMutex) Then GetStatusFromEUI and GetDataFromEUI cannot call WaitForSingleObject because you already own the mutex - the wait will wait forever. If speed is an issue (but it's probably not since ActiveX is in there in the first place) you can always double buffer the data. You *can* use RtlMoveMemory to move stuff around, but you'd probably want to set up an explicit rep movsd to get it done as fast as possible. There can of course be other answers to your problem. For instance, you might want to make a buffer an object and pass it to VEE along with the event. In this case there is no shared memory and the problem doesn't arise. IOW your wrapper becomes more of an assembly line than a way-station. Execution flows in a circle rather than having an input side and an output side. That's a much more COM solution. -SHAWN- --- You are currently subscribed to vrf as: [email=r***@soco.agilent.com]r***@soco.agilent.com[/email] To subscribe send an email request to "owner-vrf@it.lists.it.agilent.com". To unsubscribe send a blank email to "leave-vrf@it.lists.it.agilent.com". To send messages to this mailing list, email "vrf@agilent.com". If you need help with the mailing list send a message to "owner-vrf@it.lists.it.agilent.com". Search the "unofficial vrf archive" at "www.oswegosw.com/vrf_archive/". |
|
|
|
|
|
>当订阅者订阅>事件时,发布者>(发送到COM子系统)的实际调用是>发布者的线程。
对订户的调用是在系统>线程(COM)上进行的,并在>订户的thread.Man上接收,但读取不好。 这有点不对劲。 系统COM线程不是代理事件。 可以这样做但不是默认情况下。 经纪人通过一种kludgy机制发生(我认为无论如何都是愚蠢的,但推理是有效的)。 特定的*种类的公寓线程确切地确定了发生了什么。 它实际上变得非常复杂,但是在你无法使用库注册回调函数的情况下,你正在使用它可能是最好的做事方式。这就是重点。 如果您可以选择注册回调而不是在包装器中处理事件。 你仍然需要保护你的缓冲,但你的内心会更快.- SHAWN ----您目前订阅vrf为:r***@soco.agilent.com要订阅发送电子邮件请求“owner-vrf @ it .lists.it.agilent.com“。要取消订阅,请发送一封空白电子邮件至”leave-vrf@it.lists.it.agilent.com“。要发送邮件至此邮件列表,请发送电子邮件至”vrf@agilent.com“。 如果您需要有关邮件列表的帮助,请发送邮件至“owner-vrf@it.lists.it.agilent.com”。在“www.oswegosw.com/vrf_archive/”上搜索“非官方vrf档案”。 以上来自于谷歌翻译 以下为原文 > When a subscriber subscribes to an > event, the actual call the publisher > makes (to the COM subsystem) is on > the publisher's thread. The call to > the subscriber is made on a system > thread (COM's) and received on the > subscriber's thread. Man, that doesn't read well. And it's kinda wrong. The system COM thread does not broker events. It can be made to do so but not by default. The brokerage happens through a kind of kludgy mechanism (well I think it's kludgy anyway, but the reasoning is valid). The particular *kind* of apartment threading determines exactly what happens. It actually gets pretty complicated, but in the case where you can't register a callback function with the library you're using it's probably the best way to do things. And that's a point. If you have the option of registering a callback instead of handling an event in your wrapper do so. You'll still have to guard your buffer, but your in side will be faster. -SHAWN- --- You are currently subscribed to vrf as: [email=r***@soco.agilent.com]r***@soco.agilent.com[/email] To subscribe send an email request to "owner-vrf@it.lists.it.agilent.com". To unsubscribe send a blank email to "leave-vrf@it.lists.it.agilent.com". To send messages to this mailing list, email "vrf@agilent.com". If you need help with the mailing list send a message to "owner-vrf@it.lists.it.agilent.com". Search the "unofficial vrf archive" at "www.oswegosw.com/vrf_archive/". |
|
|
|
|
只有小组成员才能发言,加入小组>>
1844 浏览 0 评论
2739 浏览 1 评论
2640 浏览 1 评论
2449 浏览 5 评论
3458 浏览 3 评论
1844浏览 0评论
416浏览 0评论
/9
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-12-1 21:33 , Processed in 2.088147 second(s), Total 72, Slave 55 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191

淘帖
1050