除非我使用BeginInvoke(),否则会延迟扫描程序? [英] Delay with scanner unless I use BeginInvoke()?

查看:94
本文介绍了除非我使用BeginInvoke(),否则会延迟扫描程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,

目前我的目标机器在启用扫描仪方面存在轻微问题。它在应用程序的某些部分被禁用并启用,原因很充分,但无论何时禁用它(或其启用的属性为false),然后
启用它(将enabled属性设置为true),大约需要3-4这样做几秒钟。这会冻结用户界面3-4秒。 

I am currently having a slight issue with my target machine when it comes to enabling the scanner. It gets disabled and enabled during certain parts of the applications for good reasons, but whenever it is disabled (or its enabled property is false) then you enable it (setting enabled property to true), it takes about 3-4 seconds to do so. This is freezing the user interface for that 3-4 seconds. 

我使用this.InvokeRequired()进行了一些检查,认为它没有在创建它的同一个线程上执行但这不是必需的。然后我认为这可能是一个驱动程序问题,但后来我只是使用方法调用者对象调用该方法,并且
调用开始调用,它工作正常。但我很困惑,因为我认为如果需要调用并且与用户界面不在同一个线程上,则需要方法调用者。 

I did some checks using this.InvokeRequired() thinking it wasn't executing on the same thread that it was created on but this is not required. Then I thought this may be a driver issue but then I just called the method using a method invoker object, and call begin invoke and it works fine. But I am confused as I thought method invoker was required if an invoke was required and was not on the same thread as the user interface. 

我有一些疑问,会不会这样我做过这件事会导致我现在可能看不到任何潜在的问题吗?任何人都可以解释这里发生了什么吗?如果您需要更多信息,请告知我们。

I have a few queries, will the way I have done it cause any potential problems that I might not see right now? And can anyone explain what is going on here? If you need more information then let me know.

谢谢,

Kris

推荐答案

根据我的理解,如果您直接调用该方法(或通过该方法调用),您将获得3-4秒的延迟启用扫描程序委托和调用),但如果你调用BeginInvoke则不行?您还说InvokeRequired在您调用
之前立即返回false以启用设备?

As I understand it, you are getting a 3-4 second delay enabling the scanner if you directly call the method (or call it via a delegate and invoke), but not if you call BeginInvoke ? You also say that InvokeRequired returns false immediately before your calls to enable the device ?

如果是这种情况,那么它可能是预期的(可能)。 3-4秒延迟是不幸的,我不知道为什么需要这么长时间,但它可能与该设备的服务对象有关,打开和关闭硬件
端口,或发送某种设备命令将其唤醒等等。

If this is the case then it is sort of expected (probably). The 3-4 second delay is unfortunate and I'm not sure why it would take that long, but it is probably something to do with the service object for that device opening and closing the hardware port, or sending some kind of command to the device to wake it up etc.

就影响你的用户界面的原因而言,以及为什么begininvoke有效,我相信你对于线程如何有一些轻微的混淆在ui中工作。

In terms of why this is affecting your user interface, and why begininvoke works, I believe you have some slight confusion going on around how threading works in the ui.

如果从不是主用户界面线程的线程调用它,InvokeRequired应该返回true。这意味着您调用的几乎所有代码都没有在另一个线程上显式启动(使用线程池或新的线程对象),或者
通过控件或表单的Invoke方法调用的任何代码都将在主用户界面线程上运行。如果该线程忙于执行某些操作,那么您的UI将被阻止并显示为冻结。即使只是在按钮
点击事件中加入一些慢速代码也会导致此问题,与设备或Pos .Net或其他任何事情无关......如果UI线程繁忙,则ui似乎是冻结。

InvokeRequired should return true if you are calling it from a thread that is NOT the main user interface thread. That means that almost any code you call that wasn't explicitly started on another thread (using the thread pool or a new thread object), or any code that has been called via the Invoke method of a control or form will be running on your main user interface thread. If that thread is busy doing something, then your UI is blocked and will appear to freeze. Even just putting some slow code in a button click event will cause this, nothing to do with devices or Pos .Net or anything else... if the UI thread is busy, the ui will appear to be frozen.

InvokeRequired返回false的事实表明你的代码IS在主要的ui 线程(窗口和控件创建的线程)上运行,因此它将阻止ui同时启用或禁用
设备的通话正在进行中。在控件或窗体上调用Invoke将无济于事,因为Invoke旨在专门在主ui线程上运行代码...所以如果你已经在那个线程上它将不会做任何事情,如果你在另一个线程,你现在刚刚做了
问题更糟糕的是回到你不想要的线程。

The fact that InvokeRequired is returning false indicates your code IS running on the main ui thread (the thread the window and controls were created on) and therefore it will block the ui while the calls to enable or disable the device are in progress. Calling Invoke on a control or form won't help, since Invoke is designed to specifically run code on the main ui thread... so if you're already on that thread it won't do anything, and if you're on another thread you've now just made the problem worse by going back to the very thread you don't want to be on.

然而,BeginInvoke是另一个商店。 BeginInvoke和EndInvoke虽然它们与Invoke方法具有相似的名称,但实际上是框架提供的用于在后台线程上执行工作的方法。当你调用BeginInvoke时,你实际上是
要求.Net框架执行你传递给线程池中一个线程的委托所指向的代码 - 这不会是ui线程,所以这不会导致您的应用程序用户界面要冻结,因为它可以继续工作,而其他
线程交易到设备。

BeginInvoke however, is another store. BeginInvoke and EndInvoke, although they have similar names to the Invoke method, are actually methods provided by the framework for performing work on background threads. When you call BeginInvoke you are actually asking the .Net framework to execute the code pointed to by the delegate you pass on a thread in the threadpool - which won't be the ui thread, an so this won't cause your applications user interface to freeze since it can continue working while the other thread deals to the device.

我简化了一些事情;在表单中提前调用InvokeRequired / Invoke或控制生命周期可能存在问题,我认为表单或控件(而不是委托或其他.Net对象)上的BeginInvoke也可以调用回主线程
但是在封面上使用postmessage而不是sendmessage ......但所有这些都是技术细节,在这一点上可能是不相关的。

I've simplified things a bit; there can be issues with calling InvokeRequired/Invoke early in a form or controls life cycle, and I think BeginInvoke on a form or control (rather than a delegate or another .Net object) may also invoke back to the main thread but using postmessage rather than sendmessage under the covers... but all of that is technical detail that probably isn't relevant at this point.

我只想说你是否对设备做了什么在ui线程上需要很长时间,你的ui会挂起。当你调用BeginInvoke时,你是专门在线程池中的线程上运行那个代码而不是ui线程,所以它不会挂起。

Suffice to say if you doing anything with the device that takes a long time on the ui thread, your ui will hang. When you call BeginInvoke, you are specifically running that code on a thread in the threadpool which IS NOT the ui thread, so it won't hang.

至于是否会导致你有什么问题,很难说。可能它不会,但它取决于。它取决于服务对象是否是线程安全的(对于线程安全的给定定义)。它会说明扫描程序的Pos .Net类
是否是线程安全的(同样适用于给定的线程安全定义),它还取决于你的主要ui线程(或者实际上是否有任何其他线程) )将尝试在另一个线程
已完成的启用/禁用之前使用扫描程序。

As for whether or not this will cause you any problems, it's hard to say. Probably it won't, but it depends. It depends on whether the service object is thread-safe (for a given definition of thread-safe). It depdends on whether or not the Pos .Net classes for scanners are thread-safe (again for a given defintion of thread-safe) and it also depends on whether your main ui thread (or indeed any other thread) will ever try to use the scanner before the enable/disable that occurs on another thread has completed.

如果您在任何地方添加代码,您将访问设备以与其同步启用或禁用可能在另一个线程上运行的进程(可能使用System.Threading.ManualResetEvent对象),或者如果在设备未就绪时捕获异常抛出
并在失败之​​前重试几次(丑陋) ,但仍然可以作为解决方案)然后你可能没问题。如果你不这样做,那么可以想象(甚至可能)你可能因竞争条件而出错,但这取决于你的代码和
使用场景。

If you add code anywhere you access the device to synchronise with the enable or disable process that might be running on another thread (perhaps using an System.Threading.ManualResetEvent object), or if you trap exceptions throw when a device isn't ready and retry a couple of times before failing (ugly, but still workable as a solution) then you are probably ok. If you don't do that, then it is conceivable (perhaps even probably) you could get errors due to race conditions, but that depends on your code and usage scenarios.



 


 


这篇关于除非我使用BeginInvoke(),否则会延迟扫描程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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