[...]
But why are you setting environment variables anyway? That's kind of an
archaic thing to do. Do you have a requirement for compatibility with
some older software that uses the variables?
Nope.. no such requirement. Its just that my application is kinda
funny in the sense it runs multiple times with different command line
parameters. I had to maintain some state between invocations. I
could have used the registry obviously but went the Environment
variable route for no particular reason.
Well, the environment variables wind up in the registry anyway. IMHO, if
that's acceptable to you, you should probably just use the registry
directly.
In a .NET application, the other alternative would be a configuration
file. In .NET 2.0 and later, the Settings class provides a very nice,
easy way to persist user-specific data and IMHO would be a much better
solution than using environment variables.
[...]
But I am still curious as to why this problem is not cropping up with
a plain vanilla console application!
I'm curious too. There's probably a reasonably obvious explanation for
someone who knows more about the exact implementation. I did notice when
I was looking into this yesterday that the unmanaged Win32 API doesn't
actually provide for this functionality. The docs say to implement it
yourself by saving the data to the registry directly, and then
broadcasting a WM_SETTINGCHANGED message.
Assuming .NET took that advice, it makes me wonder if there's some sort of
interaction with the broadcast of that message, but I don't know what it
would be. Possibly the broadcast has to wait for a timeout because your
application is stuck trying to change the registry and can't receive it?
That would explain why the console application works fine, as it may skip
the window message broadcasting, or at least not having a window itself
would not wind up being a recursive bottleneck in the broadcast. It would
also be consistent with the delay being practically identical on my
computer as on yours (i.e. it's not dependent on hardware configuration,
but rather some built-in timing issue).
Of course, under that theory it should be the case that once the setting
of the registry settings are moved to another thread, it should not take
so long. So, I tried that. And in fact, doing so makes it work a _lot_
faster. It's still slower than I'd think, but on my computer it completes
in between eight to nine tenths of a second when executing the environment
variables on a separate thread. Given all the overhead for dealing with
the broadcast of the window message, thread context switches, etc. maybe
that's not an unreasonable amount of time. It's definitely a lot better
than 10 seconds.
So: have I proved what's going on? Nope...I still don't really know
what's going on. But there's some decent evidence in favor of my theory.
This also brings up a related question. The UI and this functionality
are two separate beasts. The goal is I must be able to rip out this
functionality and use it elsewhere (maybe as a standalone console app)
without worrying about tightly-binding it to the UI logic. However
the problem is if I use the BackgroundWorker class and if I want to
report the progress percentage to the UI from the functionality, I
have no choice but to pass a reference to the BackgroundWorker class
to the said functionality, right?
I'm not sure exactly what you mean, but generally the answer is "no".
BackgroundWorker does not depend on a GUI at all. You do not need to
subscribe to the ProgressChanged event, and even if you do, the subscriber
does not need to be a GUI component. Without the synchronization context
that the GUI provides, the event will be raised in the same thread doing
the work, rather than marshaled over to the GUI thread. But otherwise it
works fine.
Do I now strongly-couple UI with business logic?
That shouldn't be necessary. If you still think it is, maybe you can
explain in greater detail why you think it is. That would help provide
the context so that I or someone else can better explain why it's not.
Pete