By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
457,953 Members | 1,564 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 457,953 IT Pros & Developers. It's quick & easy.

Winforms, Shown Event and SetEnvironmentVariable

P: n/a

I am running into a weird problem in my ultra-simple Winforms
application written in C#.

In the Form.Shown event I set a couple of environment variables using
the standard SetEnvironmentVariable API like so:

Environment.SetEnvironmentVariable("someKey", somevalue,
EnvironmentVariableTarget.User);

I have 2 such calls. Amazingly it takes nearly 10 seconds for these
two calls to execute! If I comment out these 2 calls and run, the
application is just spiffy and the dialog comes up in no time.
Because it takes 10 seconds for these calls to execute, the dialog
kinda hangs before becoming responsive for that duration of time
(obviously because the UI thread is held up).

Am I doing something wrong?

Feb 14 '08 #1
Share this Question
Share on Google+
8 Replies


P: n/a
On Feb 14, 3:50 pm, Dilip <rdil...@lycos.comwrote:
I am running into a weird problem in my ultra-simple Winforms
application written in C#.

In the Form.Shown event I set a couple of environment variables using
the standard SetEnvironmentVariable API like so:

Environment.SetEnvironmentVariable("someKey", somevalue,
EnvironmentVariableTarget.User);

I have 2 such calls. Amazingly it takes nearly 10 seconds for these
two calls to execute! If I comment out these 2 calls and run, the
application is just spiffy and the dialog comes up in no time.
Because it takes 10 seconds for these calls to execute, the dialog
kinda hangs before becoming responsive for that duration of time
(obviously because the UI thread is held up).

Am I doing something wrong?
Apologies.. false alarm!
It was a different problem.
Feb 14 '08 #2

P: n/a
On Thu, 14 Feb 2008 14:06:28 -0800, Dilip <rd*****@lycos.comwrote:
Apologies.. false alarm!
It was a different problem.
What was it? As I mentioned, I was able to easily reproduce what you
described. Are you saying that you're not actually having that problem?

Pete
Feb 14 '08 #3

P: n/a
On Feb 14, 4:21 pm, "Peter Duniho" <NpOeStPe...@nnowslpianmk.com>
wrote:
On Thu, 14 Feb 2008 14:06:28 -0800, Dilip <rdil...@lycos.comwrote:
Apologies.. false alarm!
It was a different problem.

What was it? As I mentioned, I was able to easily reproduce what you
described. Are you saying that you're not actually having that problem?

Pete
Peter
I am sorry once again. Its now a false alarm on top of a false
alarm :-)
My original post was accurate. Those two calls to the
SetEnvironmentVariable does take nearly 10 seconds to execute (I timed
it with System.Diagnostics.Stopwatch).

This is weird because I earlier had these calls in a console app and I
never saw this delay. Putting them in a Winforms app however
introduces it. I can't understand why.

I am going to run CLR profiler and see what is bottlenecking it. I
haven't read your other post yet.
Will get to it after I post this.
Feb 15 '08 #4

P: n/a
On Sat, 16 Feb 2008 09:24:45 -0800, Willy Denoyette [MVP]
<wi*************@telenet.bewrote:
I can't repro this using a minimal Forms applications that sets two
environment variables in the Shown handler.
The SetEnvironmentVariable calls take less than 2 millisecond. to
complete.
Are you running in a local account, or are you running in a domain
account?
What version of the framework and OS are you running?
I was able to reproduce the behavior easily. So, from my configuration:

Windows XP SP2, IE7 (it shouldn't matter, but as we know it sometimes
does), all critical updates installed (including this month's release).
..NET 2.0 installed (SP1, if I recall correctly). User is a
restricted/limited user, local account, and the target for the call to
SetEnvironmentVariable is EnvironmentVariableTarget.User.

As I noted in a different message, running the code in the GUI thread
results in a 10 second delay (I didn't measure the two calls
independently, so I don't know if it's a single 10 second delay, or two 5
second delays). Running the same exact code in a thread pool thread (via
BackgroundWorker) results in a much smaller delay (700-900ms...still
longer than I'd expected, but much more acceptable).

Are you sure you're using the EnvironmentVariableTarget.User as the target
in your tests?

Pete
Feb 16 '08 #5

P: n/a
"Peter Duniho" <Np*********@nnowslpianmk.comwrote in message
news:op***************@petes-computer.local...
On Sat, 16 Feb 2008 09:24:45 -0800, Willy Denoyette [MVP]
<wi*************@telenet.bewrote:
>I can't repro this using a minimal Forms applications that sets two
environment variables in the Shown handler.
The SetEnvironmentVariable calls take less than 2 millisecond. to
complete.
Are you running in a local account, or are you running in a domain
account?
What version of the framework and OS are you running?

I was able to reproduce the behavior easily. So, from my configuration:

Windows XP SP2, IE7 (it shouldn't matter, but as we know it sometimes
does), all critical updates installed (including this month's release).
.NET 2.0 installed (SP1, if I recall correctly). User is a
restricted/limited user, local account, and the target for the call to
SetEnvironmentVariable is EnvironmentVariableTarget.User.

As I noted in a different message, running the code in the GUI thread
results in a 10 second delay (I didn't measure the two calls
independently, so I don't know if it's a single 10 second delay, or two 5
second delays). Running the same exact code in a thread pool thread (via
BackgroundWorker) results in a much smaller delay (700-900ms...still
longer than I'd expected, but much more acceptable).

Are you sure you're using the EnvironmentVariableTarget.User as the target
in your tests?
Yep, these two:
Environment.SetEnvironmentVariable("someKey", "1",
EnvironmentVariableTarget.User);
Environment.SetEnvironmentVariable("someOtherKey", "2",
EnvironmentVariableTarget.User);

in Shown handler.

Running V2 SP1 of the FW on VISTA.
Timing done using "QueryThreadCycleTime" API (Vista and up), with Processor
clock at fixed rate.
Total time for the two consecutive calls: ~3.6 msec. on 2.2Ghz Dual core
AMD64
~3 msec. on 3GHz Intel Core Duo.

Willy.
Feb 16 '08 #6

P: n/a
On Sat, 16 Feb 2008 13:42:49 -0800, Willy Denoyette [MVP]
<wi*************@telenet.bewrote:
Yep, these two:
Environment.SetEnvironmentVariable("someKey", "1",
EnvironmentVariableTarget.User);
Environment.SetEnvironmentVariable("someOtherKey", "2",
EnvironmentVariableTarget.User);

in Shown handler.

Running V2 SP1 of the FW on VISTA.
Timing done using "QueryThreadCycleTime" API (Vista and up), with
Processor clock at fixed rate.
Why are you doing that? The question here is elapsed time, not the CPU
time consumed by the thread for the calls.

If you just put a Stopwatch in the Shown event handler, start it before
the two calls, and check the Elapsed time after them, what results do you
get?

Not that it's relevant to this question IMHO, but what's the .NET API for
the QueryThreadCycleTime call (if any)? I can only find the unmanaged
version. Is there a managed way to get at that? Maybe in WMI?

Pete
Feb 17 '08 #7

P: n/a
"Peter Duniho" <Np*********@nnowslpianmk.comwrote in message
news:op***************@petes-computer.local...
On Sat, 16 Feb 2008 13:42:49 -0800, Willy Denoyette [MVP]
<wi*************@telenet.bewrote:
>Yep, these two:
Environment.SetEnvironmentVariable("someKey", "1",
EnvironmentVariableTarget.User);
Environment.SetEnvironmentVariable("someOtherKey" , "2",
EnvironmentVariableTarget.User);

in Shown handler.

Running V2 SP1 of the FW on VISTA.
Timing done using "QueryThreadCycleTime" API (Vista and up), with
Processor clock at fixed rate.

Why are you doing that? The question here is elapsed time, not the CPU
time consumed by the thread for the calls.
One reason is higher precision, initially I used Stopwatch and soon found
out that the elapsed time was way below 1 second (see later), also, I don't
like to use Stopwatch for anything that takes less than a second.
The other reason is that I wanted to measure the time taken by the
*current* UI thread to perform these two API calls, not the time taken by
the other threads in the system. The reason is that SetEnvironmentVariable
calls Win32's "SendMessageTimeout" to broadcast a message to all top level
windows (except the owning window) and does not return before the message
has been processed by all *other* top level windows or after a 1000 msec.
time-out period (per window). When the system broadcasts a message to a
top-level window who's thread doesn't pump it's message queue, it will wait
a max of 5 seconds before returning, which looks like what's happening in
your (and the OP's) case, though I don't understand why it's working from a
console app.
If you just put a Stopwatch in the Shown event handler, start it before
the two calls, and check the Elapsed time after them, what results do you
get?
~90-100 msecs. using ...
double elapsed = ((double)sw.ElapsedTicks/swFrequency);
with ~10 top-level windows.
This is considerably longer merely because of the extra thread switches
Not that it's relevant to this question IMHO, but what's the .NET API for
the QueryThreadCycleTime call (if any)? I can only find the unmanaged
version. Is there a managed way to get at that? Maybe in WMI?
QueryThreadCycleTime, QueryProcessCycleTime, QueryIdleProcessorCycleTime and
a couple of others are new Win32 API's in Vista and up.
..NET lags behind here, so the only way to use these high precision low
latency counters is by PInvoke.
WMI does/can't expose this, but the VS profiler can be configured to use
these counters, also ETW uses the high precision counters on Vista and
WS2008.

Willy.
Feb 17 '08 #8

P: n/a
"Willy Denoyette [MVP]" <wi*************@telenet.bewrote in message
news:%2****************@TK2MSFTNGP03.phx.gbl...
"Peter Duniho" <Np*********@nnowslpianmk.comwrote in message
news:op***************@petes-computer.local...
>On Sat, 16 Feb 2008 13:42:49 -0800, Willy Denoyette [MVP]
<wi*************@telenet.bewrote:
>>Yep, these two:
Environment.SetEnvironmentVariable("someKey", "1",
EnvironmentVariableTarget.User);
Environment.SetEnvironmentVariable("someOtherKey ", "2",
EnvironmentVariableTarget.User);

in Shown handler.

Running V2 SP1 of the FW on VISTA.
Timing done using "QueryThreadCycleTime" API (Vista and up), with
Processor clock at fixed rate.

Why are you doing that? The question here is elapsed time, not the CPU
time consumed by the thread for the calls.
One reason is higher precision, initially I used Stopwatch and soon found
out that the elapsed time was way below 1 second (see later), also, I
don't like to use Stopwatch for anything that takes less than a second.
The other reason is that I wanted to measure the time taken by the
*current* UI thread to perform these two API calls, not the time taken by
the other threads in the system. The reason is that SetEnvironmentVariable
calls Win32's "SendMessageTimeout" to broadcast a message to all top level
windows (except the owning window) and does not return before the message
has been processed by all *other* top level windows or after a 1000 msec.
time-out period (per window). When the system broadcasts a message to a
top-level window who's thread doesn't pump it's message queue, it will
wait a max of 5 seconds before returning, which looks like what's
happening in your (and the OP's) case, though I don't understand why it's
working from a console app.
>If you just put a Stopwatch in the Shown event handler, start it before
the two calls, and check the Elapsed time after them, what results do you
get?
~90-100 msecs. using ...
double elapsed = ((double)sw.ElapsedTicks/swFrequency);
with ~10 top-level windows.
This is considerably longer merely because of the extra thread switches
>Not that it's relevant to this question IMHO, but what's the .NET API for
the QueryThreadCycleTime call (if any)? I can only find the unmanaged
version. Is there a managed way to get at that? Maybe in WMI?
QueryThreadCycleTime, QueryProcessCycleTime, QueryIdleProcessorCycleTime
and a couple of others are new Win32 API's in Vista and up.
.NET lags behind here, so the only way to use these high precision low
latency counters is by PInvoke.
WMI does/can't expose this, but the VS profiler can be configured to use
these counters, also ETW uses the high precision counters on Vista and
WS2008.

Willy.



Please note that I don't have handlers for WM_SETTINGCHANGE in the other
running windows applications, other than the default handler.

Willy.

Feb 17 '08 #9

This discussion thread is closed

Replies have been disabled for this discussion.