打断冗长的序列 [英] interrupting a lengthy sequence

查看:110
本文介绍了打断冗长的序列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个很长的操作序列,在Windows窗体应用程序的状态窗口中执行并报告

。有些工作是通过

后台线程完成的,但其他工作却没有。我想知道如果用户按下Escape(或者甚至只是一个Shift键,如果那是
更简单),如何识别

,这样我就可以中止剩余的前台操作。要

识别我试过的换档键:

if((Control.ModifierKeys& Keys.Shift)== Keys.Shift){...}

我的代码每隔一段时间就包含一个Thread.Sleep(100)以允许用户识别,或者我认为可以识别
键击。但是,无论是击键还是

按钮点击都无法识别。我错过了什么?

I have a lengthy sequence of operations that are executed and reported on
in a status window in a Windows Form application. Some work is done by
background threads but other work is not. I am wondering how to recognize
if the user presses an Escape (or even just a Shift key if that is
simpler) so I may then abort the remaining foreground operations. To
recognize a shift key I tried:
if ((Control.ModifierKeys & Keys.Shift) == Keys.Shift) { ... }
My code included a Thread.Sleep(100) every so often to allow the user
keystrokes to be recognized, or so I thought. But neither keystrokes nor
button clicks are being recognized. What am I missing?

推荐答案

" michael sorens" < m _ ******** @ community.nospamwrote in message

news:op *************** @ spo-cont-2- dt.itron.com ...

我有一个冗长的操作序列,在Windows窗体应用程序的状态窗口中执行并报告

。有些工作是通过

后台线程完成的,但其他工作却没有。我想知道如果用户按下Escape(或者甚至只是一个Shift键,如果那是
更简单),如何识别

,这样我就可以中止剩余的前台操作。要

识别我试过的换档键:

if((Control.ModifierKeys& Keys.Shift)== Keys.Shift){...}

我的代码每隔一段时间就包含一个Thread.Sleep(100)以允许用户识别,或者我认为可以识别
键击。但是,无论是击键还是

按钮点击都无法识别。我缺少什么?


你需要给你的应用程序时间来处理消息循环。您可以通过调用Application.DoEvents或在

线程中运行整个过程来执行此操作




Michael
"michael sorens" <m_********@community.nospamwrote in message
news:op***************@spo-cont-2-dt.itron.com...
I have a lengthy sequence of operations that are executed and reported on
in a status window in a Windows Form application. Some work is done by
background threads but other work is not. I am wondering how to recognize
if the user presses an Escape (or even just a Shift key if that is
simpler) so I may then abort the remaining foreground operations. To
recognize a shift key I tried:
if ((Control.ModifierKeys & Keys.Shift) == Keys.Shift) { ... }
My code included a Thread.Sleep(100) every so often to allow the user
keystrokes to be recognized, or so I thought. But neither keystrokes nor
button clicks are being recognized. What am I missing?

You need to give your app time to process the message loop. You can do this
by calling Application.DoEvents or by running the entire process in a
thread.

Michael


似乎这样做;感谢指针!
That seems to do it; thanks for the pointer!


很酷,很高兴看到你的问题得到解决。


是的,Application.DoEvents是正确的解决这个问题的方法。我想

与您分享更多背景信息:


Winform GUI通常在单个线程中运行,因此当GUI线程为

处理一个长度操作,它不能回到GUI消息循环

来接收各种消息来处理。由于键盘事件是通过消息循环分配给GUI控件的,因此这个长度处理

将导致应用程序对键盘无响应。另一方

效果是应用程序无法在

消息循环中处理WM_PAINT消息,这意味着应用程序无法重新绘制其UI。

这两个副作用将导致应用程序挂起给最终用户。


因此,要解决此问题,正常的解决方案是调用

。Application.DoEvents()方法在长度处理代码中每隔几个b
时间。 Application.DoEvents()方法将尝试删除和处理当前在消息队列中的所有

Windows消息。因此,所有待处理的

WM_PAINT消息和键盘消息将在长度

操作期间处理,这使得应用程序键盘能够识别和UI

负责。


这个场景的另一个常见解决方案是在后台线程中放置长度操作

,以便GUI线程可以继续使用

消息循环而不阻塞。 Chris Sells在下面的文章中演示了这项技术



Windows窗体中的安全,简单多线程,第1部分
http://msdn2.microsoft.com/en-us/library/ms951089.aspx


注意:在Winform中进行多线程处理时,要记住的关键点是

.Net Windows Forms使用单线程单元(STA) model

,因为Windows Forms基于原生的Win32窗口本身就是
apartment-threaded。 STA模型意味着可以在任何线程上创建一个窗口,但是一旦创建就无法切换线程,并且所有函数都必须在其创建线程上进行调用。因此虽然背景

线程想要操纵GUI控件的方法/属性,但它必须使用Control.Invoke / BeginInvoke方法编组调用,或者这可能是

导致一些奇怪且难以检测线程安全的问题。有关更多信息,请参阅下面的文章



多线程Windows窗体控件示例
http://msdn.microsoft.com/library/de ... us / cpguide / htm

l / cpconDevelopingMultithreadedWindowsFormsControl.as p


如果您仍需要任何帮助或任何不清楚的地方,请随时告诉

我,谢谢。


祝你好运,

Jeffrey Tan

Microsoft在线社区支持

============================================ ======

通过电子邮件收到我的帖子通知?请参阅
http://msdn.microsoft .com / subscripti ... ult.aspx#notif

ications。


注意:MSDN托管新闻组支持服务是针对非紧急问题

如果社区或微软支持人员在1个工作日内做出初步回复是可以接受的。请注意,每个跟随

的响应可能需要大约2个工作日作为支持

专业人士与您合作可能需要进一步调查才能达到

最有效的分辨率。该产品不适用于需要紧急,实时或基于电话的交互或复杂的b $ b项目分析和转储分析问题的情况。这种性质的问题最好通过联系

Microsoft客户支持服务(CSS)处理
href =http://msdn.microsoft.com/subscriptions/support/default.aspx\"target =_ blank> http://msdn.microsoft.com/subscripti...t/default.aspx

======================================== ==========

此帖子按原样提供。没有保证,也没有授予任何权利。

Cool, glad to see your problem is resolved.

Yes, Application.DoEvents is the correct way for this issue. I want to
share some more background information to you:

Winform GUI normally runs in a single thread, so when the GUI thread is
processing a length operation, it can not go back to the GUI message loop
to receive various messages to process. Since the keyboard events are
dispatched to the GUI controls through message loop, this length processing
will cause the application to be unresponsive to keyboard. Another side
effect is that the application can not process WM_PAINT message in the
message loop, which means the application can not re-paint its UI anymore.
These 2 side effects will result in application-hang to the end user.

So, to resolve this problem, the normal solution is calling
Application.DoEvents() method in the length processing code every a few
time. Application.DoEvents() method will try to remove and process all
Windows messages currently in the message queue. So all the pending
WM_PAINT messages and keyboard messages will be processed during the length
operation, which makes the application keyboard aware of and UI
responsible.

Another common solution to this scenario is placing the length operation
work in the background thread so that the GUI thread can continue its
message looping without blocking. Chris Sells demonstrates this technology
in the article below:
"Safe, Simple Multithreading in Windows Forms, Part 1"
http://msdn2.microsoft.com/en-us/library/ms951089.aspx

Note: while doing multithreading in Winform, the key point to remember is
that .Net Windows Forms uses the single-threaded apartment (STA) model
because Windows Forms is based on native Win32 windows that are inherently
apartment-threaded. The STA model implies that a window can be created on
any thread, but it cannot switch threads once created, and all function
calls to it must occur on its creation thread. So while the background
thread wanted to manipulate the GUI controls methods/properties, it must
marshal the calling with Control.Invoke/BeginInvoke methods, or this may
cause some strange and hard to detect thread-safe issue. Please refer to
the the article below for more information:
"Multithreaded Windows Forms Control Sample"
http://msdn.microsoft.com/library/de...us/cpguide/htm
l/cpconDevelopingMultithreadedWindowsFormsControl.as p

If you still need any help or anything unclear, please feel free to tell
me, thanks.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscripti...ult.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscripti...t/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.


这篇关于打断冗长的序列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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