I have a C# library that does some file processing. I created a console and desktop application that uses the library and processes a 256mb file in about 1min. I then created a WCF service hosted in a windows service which uses the same file processing library yet takes 10x longer to process the same 256mb file when called from a website. The windows service is running under a domain account with administrator privileges.
The overhead in calling the WCF service is very fast yet the LoadFile method takes much much longer. I tried increasing the process priority during startup via
Process.GetCurrentProcess ().PriorityClass = ProcessPriorityClass.High;
to no avail. I've run this service on a Win7 64bit desktop system (6gb), 2003 XP 32bit server (4gb) and 2008 R2 32bit server (4bg) all with similar results. The console and desktop apps each process the file in about 1min on the above system. The process does not appear to be memory constrained and entering swapville.
Are windows services somehow process constrained? Would I get better results running the WCF service under IIS?
EDIT: I tried calling the library directory from the website and that too takes 10x longer than the console or desktop application.
UPDATE: Turns out it was Log4PostSharp. The console and desktop apps didn't have any traces of log4net in the configuration files yet the website and windows service did. There was a log4net TraceAppender silently eating up precious CPU cycles.
I cannot think why the behaviour you describe is happening - it does seem very strange. Since you are processing a relatively large file in memory though, the garbage collector may be affecting it. You could try changing the mode the garbage collector runs in to see if it has any effect.
The garbage collector has three modes - workstation, server and concurrent. Each one behaves in a different way and is optimised for different types of applications. Workstation mode is the default mode, and is what all processes run using unless configured to use something else. More info about the modes can be found here.
Try explicitly setting the garbage collector to use server mode (it will only have an effect on a multi-processor machine though). To do this, put the following in your app.config file:
<configuration>
<runtime>
<gcServer enabled="true" />
</runtime>
</configuration>
Related
We're deploying .Net4-based asp.net apis to a large number of windows servers, and in order to keep aws costs low, we run them as small as possible.
The problem we're seeing is that after the vm is provisioned and code is deployed, we're seeing high cpu usage for a few minutes. Most of this cpu usage comes from the process "ngentask.exe". It's not related to app startup, we're typically seeing this happening a few minutes after the deploy continues and other cpu-heavy processes calm down.
It's also worth mentioning that as part of our deploy process, we "touch" the app by invoking a web request to a predefined "health" endpoint in the app, which is simply an empty MVC controller in most of our apps - we do this both to verify that the app is actually running, and to make sure is "warmed up" and ready to serve traffic.
Looking at the ngen.log, the timestamps match perfectly with cpu usage:
11/13/2018 14:20:13.275 [732]: Task scheduler requested starting 32-bit task
11/13/2018 14:20:13.371 [732]: Task scheduler requested starting 64-bit task
11/13/2018 14:20:13.371 [732]: Launching NGen Task, command line: "C:\Windows\Microsoft.NET\Framework\v4.0.30319\NGenTask.exe" /RuntimeWide /StopEvent:380
11/13/2018 14:20:13.371 [732]: Launching NGen Task, command line: "C:\Windows\Microsoft.NET\Framework64\v4.0.30319\NGenTask.exe" /RuntimeWide /StopEvent:860
11/13/2018 14:20:13.512 [3104]: NGen Task starting, command line: "C:\Windows\Microsoft.NET\Framework64\v4.0.30319\NGenTask.exe" /RuntimeWide /StopEvent:860
11/13/2018 14:20:13.560 [3104]: Attempting to acquire task lock.
Like I wrote, this can happen as much as 10 minutes after deploy, and by that time the app is already serving requests. This leads me to believe that these tasks are actually not needed - if they were, the app wouldn't function in the 10 minutes between deploy and the completion of these processes.
So my question is: Am I safe to disable this task? These are Windows 2016 Core servers only running a single asp.net web app, so there's no "random" gui apps getting installed or anything.
Instead of trying to disable ngen, you could manually execute it as the final step in your deployment. Ngen normally runs in the background, and is designed to optimise application startup - but ironically it seems to destroy performance for several minutes in the process. Ngen will supposedly auto start only when the server is idle - but once it starts it seems to hog the CPU for several minutes and ive seen that cause issues on smaller servers (specifically AWS Micro instances).
Below one-liner finds the newest version of ngen.exe and forces an update. It takes a couple of minutes to run, when its done the server should quieten down and behave.
& ([String] $ngenExe = ((Get-ChildItem -Path C:\Windows\Microsoft.NET\Framework64\v*\ngen.exe) | sort -Descending | Select -First 1)) update /force
See: https://learn.microsoft.com/en-us/dotnet/framework/tools/ngen-exe-native-image-generator
I have a module that performs multiple SQL Server database operations.
When I execute this module in IIS (inside RESTful Service), the execution of this module takes about twice the time it takes while executing inside desktop application in the same computer.
In both, IIS and Desktop applications, software factors such as number of database operations, data impacted, etc are same.
I tried changing various properties in application pool, but I could not lower the running time in IIS to match to that in desktop application.
Are there any settings in IIS which help lowering the running time of the module?
Is running in IIS is supposed to be slower than in normal desktop application? Why?
I have an IIS server version 8.5. I have web site and a number of web-services hosted on this web site. A number of windows services and desktop apps are working this with IIS instance. And everything is ok for some time. But some time later IIS begin to use 100% of cpu resources. I can suppose that my code is the probem, but firstly i'm doing next steps:
I'm switching off all windows services and desktop apps.
Switching off w3wp process from processes.
Restrating several times app pool, iis and site.
But after i'm startig again iis, pool and site and nothing else (nothing is using iis) i can see that iis worker process using about 20% of cpu resources. And the situation above can be repeated again after some time. It means that the problem can't be in the my code.
What can be the problem of the iis high-load then it just started and then it uses 100% of cpu?
It happens, we've all struggled with high CPU in a worker process before. It in almost all cases it is the code.
If you're threading (That's probably your answer right their)
But here's what you need to do.
Right click on the process consuming the CPU and click "Dump Process", this will create a debug file.
Then use debug diagnostic tool from Microsoft and open the file, it has a wealth of information in it. It's your starting point. Unless you're willing to share the code.
I have developed a complicated console app that do the following:
I insatll the console app as window service.
In this console app i created a web api host self site.
In addition in the background of the console i open socket connection with
another computer.
Now when i run this app(not as windows service) in VS everything works good and the app use less than 2% cpu.
When i install this app on the server it use at least 20% cpu and somtimes even 30% cpu..
Now i can't understand where is the problem..
Anyone can suggest me how can i check what exactly "eat" so much cpu??
I have a windows service (C#) installed on a server that launches every 10 minutes an executable file (C#) to process some images from one directory to another. No interaction is required with any user. Nevertheless, since the executable file as an output window, to make the service run I have to enable the "Allow service to interact with desktop" checkbox which is considered as an insecure and bad practice. How would I go about this problem? I like to have the executable separated from my windows service because
it makes it easier to debug and
doesn't require a full windows service redeploy.
sometimes I use the same windows
service to launch several
executable files at different
intervals (but all related to the same
project).
EDIT:
When the interaction with the desktop is not enabled, the console application does not get executed correctly and the following error appears inside the Windows Logs:
Faulting application myapp.exe, version 1.0.0.0, time stamp 0x4b8304c3,
faulting module KERNEL32.dll, version 6.0.6002.18005, time stamp 0x49e03821,
exception code 0xc0000142, fault offset 0x00009eed, process id 0x10ec,
application start time 0x01cab736950a64b5.
Once the desktop interaction is enabled, application gets executed normally.
Any thoughts?
Thanks a lot for your time.
If you are using Vista and later and you don't really need any interaction with the user, but have an interactive exe to execute, the Session 0 isolation feature should help alleviate some of the concerns about the 'bad practice' on having a service interact with the desktop (which in Session 0 has no physical console).
This Session 0 isolation would prevent unprivileged users from performing Shatter Attacks on your service as they get their interactive desktops in different sessions. Shatter attacks are the main reason why this 'interaction with desktop' was considered bad practice and if you are using Vista or later, it should be ok if you cannot avoid it (or will have to spend too much effort to do it).
So, if things are working fine as they are, you are probably ok.
Of course, after an OS update, things might just stop working, so it is probably better to prepare to move the dependency on interactivity out, as you don't really need it.
I know this is a bit late but in this circumstance i would use the task scheduler and not bother with the windows service. The task scheduler has a comprehensive set of scheduling options and can run console applications without issue.
If you can, I would recommend rewriting your executables that handle the move to not use an output window. If they are standard, console applications with no output, you can execute them from within a service without requiring "Allow service to interact with desktop". This provides you all of the benefits, without any changes to your service.
Is the subprocess just a console application? I've not written Windows Services, but I think perhaps just starting the subprocess without a window would be sufficient. Use the overload of Process.Start that takes a ProcessStartInfo and set ProcessStartInfo.CreateNoWindow to true.
http://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.createnowindow.aspx