On 01.06.2013 05:02, Friedrich Brunzema wrote:
> OK I get that we can't use the helper class in methods that run on a
> separate thread, because only the thread creating the window and
> controls can be used to effectuate any change.
>
> I'm attaching a patch file that shows some questions I have about
> possible violations of the above rule. Please don't commit this - its
> just a means of communicating possible problems. I'm not sure that
> Win32 allows EnableWindow() on a different thread. Setting Focus, etc
> is probably not allowed, because it causes a redraw, and the thing they
> are trying to avoid is two threads using the same GDI shared resource.
> Messing with the cursor cross thread *probably* works because of the ref
> counting, but I don't know for sure. Creating a brand new window
> (dialog) and doing stuff in the thread is OK, since that does not
> violate the rule. Making the new window a child of the window created
> on the other thread is also probably OK, since this works on a higher
> level handle. It might make sense to leave some of the comments that
> indicate which methods are possibly invoked from a separate thread -
> since those methods are then not allowed any main window changes.
You can call Window-functions like EnableWindow() on a thread, that's
not a problem. At least not if the code is otherwise thread safe.
Because if you call EnableWindow() on a thread, a message is posted to
the main thread (the one with the message queue) to do the job. The only
thing you have to be careful about are deadlocks, because your thread is
then maybe waiting for the UI thread to respond.
>
> My experience has been with C# and WPF - there the rules are very clear
> and you get an exception right-away if you don't play by the rules.
> With Win32, I think things are less clear, and things sometimes work,
> sometimes not.
>
> One way around this is to pass the STA (creator thread) id to the worker
> thread. Requesting changes to the UI could be done through a
> PostThreadMessage() [RegisterMessage], and the actual work would be done
> in the handler of the message running in the original thread.
That's the clean and proper way, but also in our case (simply enabling a
control) not necessary and IMHO total overkill.
>
> If the AsyncScheduler had a feature / way to run an action (lambda) in
> the context of the original thread after the worker thread completes,
> this would solve some problems. You could then disable UI in the
> original tread - do the action on the other thread and have the original
> thread re-enable the UI.
>
> We could, of course also just not bother with all of this business, and
> remove the class I introduced and revert the code to what it was...
Well, it would be all ok if your CLogWndHourglass class would only do
what its name implies: take care of the cursor.
But since you've added the re-enabling of the OK button there as well we
have the described problem.
I suggest instead of fully reverting your change to simply have the
CLogWndHourglass only deal with the cursor, and handle the OK button and
everything else as before: on the thread if necessary, directly if possible.
Stefan
--
___
oo // \\ "De Chelonian Mobile"
(_,\/ \_/ \ TortoiseSVN
\ \_/_\_/> The coolest interface to (Sub)version control
/_/ \_\ http://tortoisesvn.net
------------------------------------------------------
http://tortoisesvn.tigris.org/ds/viewMessage.do?dsForumId=757&dsMessageId=3056841
To unsubscribe from this discussion, e-mail: [dev-unsubscribe_at_tortoisesvn.tigris.org].
Received on 2013-06-01 15:37:58 CEST