C# Multithreading CPU usage 100% - c#

My application is a asp.net web service. There is a one more windows service ruining in the same server and trigger the web-service by specified intervals.
So in each web-service call, in side the web server, it create a new thread and start to do the task that web service suppose to do.
Some times, this started thread could not finish the assigned task, before next web service call comes. So the next web-service call create a same kind of a new thread and assign new task to the new thread.
So if I check the server in busy situations, Sometime there are 20+ parallel threads ruining.
Every thing works fine. But server (windows 2003 sp2) looks not responding some times. So I check the CPU performance in the Task Manager and it shows 100% when the web-service start to work. even if there are only 1,2 threads same thing happens.
I feel something wrong. Am i doing something conceptually wrong. Appreciate some advice.
Edit
public class EmailPrinter : System.Web.Services.WebService
public void webServiceMethod()
{
Thread email_thread = new Thread(new ThreadStart(this.downloadEmails));
email_thread.Start();
}
private void downloadEmails(object sender, DoWorkEventArgs e)
{
EmailService.init();
EmailService.ReceiveEmail();
}
}

Related

Why does sending many emails asynchronously block the site? ( using Action.BeginInvoke )

I created a page to send thousands of emails to our clients, almost 8K emails.
The sending process is taking hours, but after a while I couldn't access any page (get waiting...) in the site that is hosting the page except for static files (images etc...).
Using: IIS 6 and .Net 4.0
Code:
public static bool Send(MailSettings settings, Action<string, string[], bool> Sent = null)
{
System.Net.Mail.SmtpClient client;
...
foreach(){
try{ client.Send(message);}catch{...client.Dispose();...}
Sent.BeginInvoke(stringValue, stringArray, boolValue, null, null);
if(count++>N){
count=1;
System.Threading.Thread.Sleep(1000);
}
}
...
}
public void SentComplete(string email, string[] value, bool isSent)
{
....//DB logging
}
Note: Other sites using the same Application pool were fine!
Questions:
Is there a IIS 6.0 limitation to the number of threads for the same website?
Any Ideas if my code was causing any performance issues? Am I using Action right?
There are many things wrong with this code:
Your try catch block is very weird. You are disposing an object in
one iteration but it can be used by others. Try using block instead.
There is a maximum time for asp.net request to execute.
Don't put thread sleep in asp.net!
Yes, there is a maximum thread count in asp.net pool
If you end up blocking for one reason, you can also be blocked by the session (if you have one)... Does it work if you open a different browser?
You're firing off a whole bunch of actions to be executed in the thread pool. There is a max number of threads that the thread pool will create, after that the work items sent to the pool simply get queued up. Since you're flooding the thread pool with so many operations you're preventing the thread pool from ever having an opportunity to get a chance to work on the items added by ASP.NET to handle pages. Since static items don't need to push work to the thread pool, those items can be serviced.
You shouldn't be firing off so many items in parallel. You should be limiting the degree of parallelism to a reasonably small fixed amount. Let those handful of items that you start each process a large number of operations that you have so that the threads in the thread pool have the possibility of working on other things as well.
We regularly send 10000 client emails. I store all the details of the email in a database and then call a web service to send them. This just chuggs through them and affects nothing else. I do put the thread to sleep (in the web service) for 100ms between each call to Send ... if I don't do this firing off so many emails seems to overwhelm our mail server and we get some odd things happening.

Will IIS stop this thread?

Hello I am make a long running service class that runs diffidently but it's thread is paused all the time except for once a day when it has to check some data for my asp.net website. It is a WCF file in an asp.net website. The class inherits from this interface :
[ServiceContract]
public interface IService
{
[OperationContract]
void DoWork();
}.
This is the code it uses for creating the thread the class run on :
//Initialize the thread
Thread = new Thread(new ThreadStart(threadDoSomething));
//The thread is a background thread; it is a long running service
Thread.IsBackground = true;
//This Thread does not need much CPU attention so it is not a high priority
Thread.Priority = ThreadPriority.Lowest;
//Run the tread
Thread.Start(this);
I have heard that IIS will occasionally stop long running processes to save memory, will it stop this process?
Yes, IIS will recycle ApplicationPools when no activity has been received in a period (it's configurable).
A simple trick to avoid this is to do that thread navigate a page on your web application to avoid it but it will finally sometime recycle it after a long period.
UPDATE:
Ehm... if your app is a windows service then IIS has nothing to do with your thread...

How to continue execution of code only when windows service is completed?

I have a Windows service which performs a fairly long running task. At the moment, I spawn a new thread, which executes a method which goes off and calls this windows service. This code looks like:
Thread thread = new Thread(new ThreadStart(ExecyuteLongRunningMethod));
thread.Start();
thread.Join();
Higher up in the callstack (when this code is done), a message box popups stating the result of the operation.
However, while this block of code executes (ExecuteLongRunningMethod calls the windows svc), a message box popups stating that nothing has changed as a result of the operation, but because this is before the code block above has completed, the wrong message box appears.
Thus, the question is, what would be the proper way to only continue execution in the winforms app (this is what calls the windows svc), ONLY when the windows service is finished? I am thinking that the approach above is incorrect as the thread will call the windows service (another process), so while the windows service does its stuff, my code (winforms app) will continue. Either some sort of signaling is required, or something like named pipes?
The app is in .NET 3.5.
Thanks
Expose the status of your service execution via a WCF API and call it using netTcp or named pipes, you could poll the service or use a WCF CallBack.
Why don't you use a BackgroundWorker, so you can set an event for its completion?
In Backgroundworker running method you can run the service and wait for a manual reset event (for example) or a mutex and, when received this you can exit main method.
So OnCompleted event is raised in your main thread (UI for example) and the job is done...
In your app add a Backgroundworker and name it bgw.
Then you can do:
private void bgw_DoWork(object sender, DoWorkEventArgs e)
{
// 1. Run the service
// 2. Wait for mutex
}
private void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// Here you can handle the end of the service
// and return the status in main thread
}

C# Windows Service fails to start fast enough

I have a C# Windows Service. The OnStart() method contains 3 lines that all they do is start a thread. The class itself has no static objects that would cause a delay. It is as simple as a service can be. My code is signed by a self made key.
Edit: I just figured out that assembly isn't signed, the rest are. It uses a few assemblies which are signed but the service itself isn't.
This code is running inside a virtual machine, whenever the host is running slow and this VM is booting up, the service will fail to start with this error:
A timeout was reached (30000 milliseconds) while waiting for the ServiceName service to connect.
Setting the service to delay start fixes it but it's a long delay and it's very annoying. Has anyone else had this problem with .NET services (2.0)?
The OnStart method:
protected override void OnStart(string[] args)
{
Thread startThread = new Thread(new ThreadStart(StartThread));
startThread.IsBackground = true;
startThread.Start();
}
The StartThread method, in which all I do is call another class so that the OnStart won't have to wait for static variable initialization or for the constructor method to end.
private void StartThread()
{
Worker mainThread = new Worker(this);
mainThread.RunWorker();
}
Thank you.
I think this is most likely due to the strong name signing that you have on your executable. In general, it's not good practice to do that on executables (see here). I have also experienced the same problem in one of my projects, where an executable took an incredible amount of time to start, and turned out it was due to strong name signing the executable (.NET 2.0 as well).
Consider turning AutoLog = false. I've seen where this flag can cause the timeout you're describing.

How do I wait until a console application is idle?

I have a console application that starts up, hosts a bunch of services (long-running startup), and then waits for clients to call into it. I have integration tests that start this console application and make "client" calls. How do I wait for the console application to complete its startup before making the client calls?
I want to avoid doing Thread.Sleep(int) because that's dependent on the startup time (which may change) and I waste time if the startup is faster.
Process.WaitForInputIdle works only on applications with a UI (and I confirmed that it does throw an exception in this case).
I'm open to awkward solutions like, have the console application write a temp file when it's ready.
One option would be to create a named EventWaitHandle. This creates a synchronization object that you can use across processes. Then you have your 'client' applications wait until the event is signalled before proceeding. Once the main console application has completed the startup it can signal the event.
http://msdn.microsoft.com/en-us/library/41acw8ct(VS.80).aspx
As an example, your "Server" console application might have the following. This is not compiled so it is just a starting point :)
using System.Threading;
static EventWaitHandle _startedEvent;
static void main()
{
_startedEvent = new EventWaitHandle(false, EventResetMode.ManualReset, #"Global\ConServerStarted");
DoLongRunnningInitialization();
// Signal the event so that all the waiting clients can proceed
_startedEvent.Set();
}
The clients would then be doing something like this
using System.Threading;
static void main()
{
EventWaitHandle startedEvent = new EventWaitHandle(false, EventResetMode.ManualReset, #"Global\ConServerStarted");
// Wait for the event to be signaled, if it is already signalled then this will fall throught immediately.
startedEvent.WaitOne();
// ... continue communicating with the server console app now ...
}
What about setting a mutex, and removing it once start up is done. Have the client app wait until it can grab the mutex before it starts doing things.
Include an is ready check in the app's client interface, or have it return a not ready error if called before it's ready.
Create a WCF service that you can use for querying the status of the server process. Only start this service if a particular command is passed on the command line. The following traits will ensure a very fast startup of this service:
Host this service as the first operation of the client application
Use the net.tcp or net.pipe binding because they start very quickly
Keep this service as simple as possible to ensure that as long as the console application doesn't terminate, it will remain available
The test runner can attempt to connect to this service. Retry the attempt if it fails until the console application terminates or a reasonably short timeout period expires. As long as the console application doesn't terminate unexpectedly you can rely on this service to provide any additional information before starting your tests in a reasonably short period of time.
Since the two(the console application, and integration test app that makes client calls - as I understand) are separate application, so there should be a mechanism - a bridge - that would tell play as a mediator(socket, external file, registry, etc).
Another possibility could be that you come up with an average time the console takes to load the services and use that time in your test app; well, just thinking out loud!

Categories