A
Alex Zhitlenok
Thinking about a standard "silly" problem of giving a user an option
to cancel long drawing loop, I read a lot of articles and did some
investigations of my own. (I work with C# .Net 2003).
My application must provide a very sophisticated drawing, which is
actually a millions-length sequence of simple line or ellipse drawings
executed in a very long loop. Naturally, I'd like to give a user an
option to cancel the drawing.
I have a number of rather bad solutions and I don't see any acceptable
one.
The Solutions are:
1. The drawing loop is execute in the UI thread and calls DoEvents()
to allow "Cancel" button to be pressed. The downside is well known
(see DoEvents() method adoption discussions) – UI thread is busy and
natural events sequence is broken.
2. The drawing loop is executed not in the UI thread. The downside is
seldom exceptions. Generally, as I know, .Net does not allow drawing
from non UI thread.
3. The drawing loop is executed not in the UI thread but all drawing
operations are executed in the UI thread by calling Invoke for each
elementary drawing operation. Theoretically, this must be the correct
schema! . The downside is that Invoke() is a very expensive call, so
it works inappropriately long (see table below).
4. Using memory-stream metafile for buffering. Actually, this is not
what I need; in addition, it works even longer then #3.
Here is the execution time comparative graph for different
implementations of a loop with 2,000,000 drawing lines on my PC.
1. Execution in the UI thread (without DoEvents() calling) - time
00:00:04.6250592 (given as 1) and no "Cancel" available
2. Execution in the UI thread (calling DoEvents() on each step) -
00:00:10.5937500 (2.3 times longer)
3. Execution in a non UI thread (calling Invoke() for each drawing
operation) - 00:05:41.560314 (73.8 times longer)
4. Drawing in memory-metafile (no DoEvents() or Invoke() ) - execution
time 00:05:06.7153993 (66.3 times longer)
Of course, 5 minutes instead of 5 seconds is too much for such a
common task (a long loop cancellation). Any suggestions will be deeply
appreciated.
Alex
to cancel long drawing loop, I read a lot of articles and did some
investigations of my own. (I work with C# .Net 2003).
My application must provide a very sophisticated drawing, which is
actually a millions-length sequence of simple line or ellipse drawings
executed in a very long loop. Naturally, I'd like to give a user an
option to cancel the drawing.
I have a number of rather bad solutions and I don't see any acceptable
one.
The Solutions are:
1. The drawing loop is execute in the UI thread and calls DoEvents()
to allow "Cancel" button to be pressed. The downside is well known
(see DoEvents() method adoption discussions) – UI thread is busy and
natural events sequence is broken.
2. The drawing loop is executed not in the UI thread. The downside is
seldom exceptions. Generally, as I know, .Net does not allow drawing
from non UI thread.
3. The drawing loop is executed not in the UI thread but all drawing
operations are executed in the UI thread by calling Invoke for each
elementary drawing operation. Theoretically, this must be the correct
schema! . The downside is that Invoke() is a very expensive call, so
it works inappropriately long (see table below).
4. Using memory-stream metafile for buffering. Actually, this is not
what I need; in addition, it works even longer then #3.
Here is the execution time comparative graph for different
implementations of a loop with 2,000,000 drawing lines on my PC.
1. Execution in the UI thread (without DoEvents() calling) - time
00:00:04.6250592 (given as 1) and no "Cancel" available
2. Execution in the UI thread (calling DoEvents() on each step) -
00:00:10.5937500 (2.3 times longer)
3. Execution in a non UI thread (calling Invoke() for each drawing
operation) - 00:05:41.560314 (73.8 times longer)
4. Drawing in memory-metafile (no DoEvents() or Invoke() ) - execution
time 00:05:06.7153993 (66.3 times longer)
Of course, 5 minutes instead of 5 seconds is too much for such a
common task (a long loop cancellation). Any suggestions will be deeply
appreciated.
Alex