473,378 Members | 1,403 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,378 software developers and data experts.

interrupting a lengthy sequence

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?

Nov 22 '06 #1
13 1736
"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
Nov 22 '06 #2
That seems to do it; thanks for the pointer!
Nov 22 '06 #3
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.

Nov 22 '06 #4
Just for completeness, in many circles DoEvents() is considered a hack, with
the correct solution being to do the real work on a worker thread with
suitable UI sync code. This can be a little more work, but can help avoid
some interesting "trying to do 5 things at once" on the UI thread (not "at
once" in the CPU sense - but rather 5 separate methods started via a UI
event and interrupted by DoEvents()).

For a "utility" app, or something small, you can probably get away with
it... but once you get the knack, the "proper" way isn't much more effort -
especially if you use (for instance) the BackgroundWorker component as a
easy route in...

Marc
Nov 22 '06 #5
Thanks for all the follow-up information; there's quite a bit to digest in
those articles. Just one final point: what is the proper way to process a
TableAdapter.Fill() call in the background? That operation may take quite
a while in my application. If I hand it off to a worker thread
with the Invoke mechanism described, doesn't that still lock up the UI?
Nov 22 '06 #6
Jeffrey Tan[MSFT] <je***@online.microsoft.comwrote:
Cool, glad to see your problem is resolved.

Yes, Application.DoEvents is the correct way for this issue.
Eek, no. Tying up the UI with a long-running task and periodically
calling Application.DoEvents is a nasty way of solving the problem. In
particular, if there are *any* blocking calls (eg file IO which might
be across a network, or a database transaction) then while that
blocking operation is taking place, the UI will be hung.

This kind of problem plagues some applications, eg Visual SourceSafe,
and is a source of great annoyance to users.

<snip>
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.
That's a *far* better way of doing things.

<snip>

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Nov 22 '06 #7
michael sorens <m_********@community.nospamwrote:
Thanks for all the follow-up information; there's quite a bit to digest in
those articles. Just one final point: what is the proper way to process a
TableAdapter.Fill() call in the background? That operation may take quite
a while in my application. If I hand it off to a worker thread
with the Invoke mechanism described, doesn't that still lock up the UI?
I assume you're using data binding? If so, there's a bit of a problem -
filling the table calls UI handlers, so you have to do it in the UI
thread if you have data bindings. This is a pain. You could undo the
binding, fill the table in a different thread, and then redo the
bindings, or take the nasty hit of doing the fill in the UI thread.

Having said this, my experience with data binding is solely on 1.1 - I
believe it's been much improved in 2.0, so there may be some better
solutions there.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Nov 22 '06 #8
Hi Jon ,

Yes, I see your point. However, asking the customers to change their design
is not always practical, so I provide 2 solutions to the customer and let
them judge the choice. Sure, the second multithreading solution is better
than first one.

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.
Nov 23 '06 #9
Jeffrey Tan[MSFT] <je***@online.microsoft.comwrote:
Yes, I see your point. However, asking the customers to change their design
is not always practical, so I provide 2 solutions to the customer and let
them judge the choice. Sure, the second multithreading solution is better
than first one.
That's a reasonable thing to say - what I was most objecting to was the
idea that "Application.DoEvents is the correct way for this issue" and
"So, to resolve this problem, the normal solution is calling
Application.DoEvents() method".

Application.DoEvents should generally be regarded as a much riskier way
of doing things, IMO.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Nov 23 '06 #10
Hi Michael ,

Thanks for the feedback.

Yes, your question makes sense. Just as Jon said, if you invoke
TableAdapter.Fill() method with Control.Invoke in background thread, it
will actually still be executed in GUI thread, because the databinding code
will trigger the UI updating.

Jon's suggestion is a suitable solution. First, cutting of the databinding
by setting DataGridView.DataSource=null. Then, you may call
TableAdapter.Fill() method directly in background thread without marshal it
with Control.Invoke. This is because the TableAdapter.Fill() method totally
executed in non-GUI thread now, it will not touch the UI anymore. After
filling the DataSet in background thread, the background thread can call
Control.Invoke again to set DataGridView.DataSource to this filled dataset.

Also, you may customize the SQL statement in the SqlDataAdapter to
introduce paging algorithm, so that you only need to fill a small fraction
of the total data. You may retrieve the next page of data when the user
clicked "Next Page" button. This will reduce the time of
TableAdapter.Fill() method which will not consume much time in GUI thread
now. Actually, this paging makes sense because end user will not always
need the total large data from Database.

This delay evaluation is widely used in various components of computer.

Hope this helps.

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.
Nov 23 '06 #11
Thanks to both Jeffrey and Jon for this insight into cutting and restoring
the databinding. I was not aware that would work, so I will give it a try.
Nov 28 '06 #12
I do understand the perils and annoyance of tying up the UI, but--as
suggested--one does not always have the luxury of doing everything the
best way. :-)
Nov 28 '06 #13
Hi Michael,

Thank you for feedback the status. Ok, if you need any further help, 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.
Nov 28 '06 #14

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Leo Breebaart | last post by:
Hi all, In a GUI program I'm currently developing (wxWindows, if that matters), I am trying to get some time-consuming tasks (triggered by e.g. the user choosing a menu item) out of the...
10
by: Rithish | last post by:
Hi folks. A premature and redundant question maybe... But I have a TABLE problem. This is almost something like what I want to acheive. ----------------------------------------- | ...
4
by: Hardy Wang | last post by:
Hi, I have a win form application, when a button is clicked, a lengthy operation will be triggered. During the time program is still running, this application seems not to be able to response to...
3
by: Ed Chiu | last post by:
Hi, I have a relative lengthy .aspx page. There are buttons, datalists datagrids everywhere. When a user scrolls down to the middle of bottom of the page and click on a button, a postback...
5
by: atefshehata | last post by:
hi all, i'm using iis6 installed on win2003 , dotnet framework 1.1 . My problem is.. a page on my application have a lengthy process which takes about 4 minutes (performing database...
6
by: Cerebrus99 | last post by:
Hi all, I'm making a Windows application that does some lengthy retrieval operations from a database and possibly from a internet resource. I want to show that the operation is going on, by...
8
by: andreas | last post by:
When I do a long calculation is there a possibility to interrupt this calculation properly? For i as integer = 1 to 100000000 do something next and retrieve the i at the moment of the...
5
by: Jonah Bishop | last post by:
I'm developing a photo album web application for use on a web site, and I'm running into a problem with lengthy operations. My application allows the user to import a number of images at once into...
1
davydany
by: davydany | last post by:
Hey guys...a n00b Here for this site. I'm making a sequence class for my C++ class. And The thing is in the array that I have, lets say i put in {13,17,38,18}, when i see the current values for the...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.