I'm developing a simple test tool to verify how many HASH(SHA1) the customer server can elaborate in 1 second.
The attached sample use muti-threading to start and stop a timer that counts executed HASH.
The HASHes are sequential.
The application works well in Visual Studio, but if I run it outside the VS environment it crashes.
The problem is on increment() function in "using" section. If I comment it, everything works well!
static void increment()
{
try
{
using (SHA1 sha = new SHA1CryptoServiceProvider())
{
byte[] result;
byte[] data = new byte[20];
new Random().NextBytes(data);
result = sha.ComputeHash(data);
}
Interlocked.Increment(ref safeInstanceCount);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
The code used to start and stop the time is the following:
bool stop;
static void Main()
{
try {
TimerQueueTimer qt;
qt = new TimerQueueTimer();
TimerQueueTimer.WaitOrTimerDelegate CallbackDelete = new TimerQueueTimer.WaitOrTimerDelegate(QueueTimerCallback);
uint dueTime = uint.Parse(textBox1.Text); // string "60000" = 1 min
uint period = 0;
qt.Create(dueTime, period, CallbackDelete);
while (!stop)
{
// Thread thread = new Thread(new ThreadStart(increment));
// thread.IsBackground = true;
// thread.Start();
increment();
}
stop = false;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
private void QueueTimerCallback(IntPtr pWhat, bool success)
{
try
{
stop = true;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
How can I understand where is the error?
=
The application crashes without any exception.
I try to catch it, without success, it happened after 60 sec. (Maybe QueueTimerCallback is called?)
The application does not generate any error trace and it DOES not crash running under Visual Studio!
When it crashes it does not generate any stack trace, just a pop-up crash window giving in detail the "StackHash_xxxxx" error
Nothing to do! I've try to use Console.Read (it's a Windows app not console) but I cannot see anything. Here is the error shown! https://picasaweb.google.com/lh/photo/iHsBhRSy-DNTYVo4CpoeA9MTjNZETYmyPJy0liipFm0?feat=directlink
Your program is likely throwing an exception, and it's getting written to the console, but you don't have anything from stopping the console from closing immediately after the message is written.
Add a Console.ReadKey(); after your try/catch block.
Related
I get cItems which is a IReadOnlyCollection<IWebElement> provided by Selenium.
However. I make the function Single Thread based, it works nice. But now I wanted to increase performance and so I choosed the .Net ThreadPool.
ThreadPool.SetMaxThreads(16, 16);
IEnumerator<IWebElement> iter = cItems.GetEnumerator();
while(iter.MoveNext()) {
cThreadJobObj.Item = iter.Current;
ThreadPool.QueueUserWorkItem(new WaitCallback(GetThreadJob), cThreadJobObj.Clone()); // .Clone() is a deep clone
}
The Problem now is, that the Threads disappear, in Line 5. There isn't any Exception thrown, I think because the } catch (Exception Ex) { block isn't called.
public static void GetThreadJob(object ThreadJob) {
try {
var cThreadJob = ThreadJob as ThreadJobObj;
var IWebElement = cThreadJob.Item;
var cElem = cItem.FindElement(By.CssSelector("span.im_message_date_text"));
} catch (Exception Ex) {
Rupert.Logger.E("{Thread.GetCurrentProcessorId()} on Obj {cThreadJob.iCount}", Ex, false);
}
}
The GetThreadJob is called by all 16 Threads, and all disappear at the same line.
Update
I separated the line and the Threads disappear in this method ISearchContext.FindElement Method.
IWebElement.FindElement(By)
If I make a quickwatch on this line, this is the value:
cItem.FindElement(cSel) Function evaluation disabled because a previous function evaluation timed out. You must continue execution to reenable function evaluation. OpenQA.Selenium.IWebElement
Ok, after a long night I found out, that the .Net Limits the Sockets which could be opened, during the Selenium Process.
The default value for ServicePointManager.DefaultConnectionLimit is 2 and 10 for Asp.net. More Info
This can be avoided through this in the init of the script:
ThreadPool.SetMinThreads(Environment.ProcessorCount / 2, 25);
ThreadPool.SetMaxThreads(Environment.ProcessorCount * 4, 100);
ServicePointManager.UseNagleAlgorithm = true;
ServicePointManager.Expect100Continue = true;
ServicePointManager.DefaultConnectionLimit = 65000;
ServicePointManager.MaxServicePointIdleTime = 500;
The run() function in the following code is called from other threads simultaneously. At anytime, on any line, a ThreadAbortException might occur according to the general design of the application, which I cannot change.
I sometimes get SemaphoreFullException while calling pool.Release(). I think this occurs if a thread abort exception occurs while calling "pool.WaitOne()". During my debug tries, after SemaphoreFullException has occurred, there is no problem in running the code. After that exception, pool.WaitOne() calls and other things work just as expected.
I haven't been able to get a deadlock situation during my local debug sessions. However, in a remote computer, I have a deadlock with this code. I attach that process using remote debugger and see that the execution is locked on the line pool.WaitOne();.
I can't figure out how this would happen, and what I'm doing wrong. Any help is very appreciated.
private static object poolLocker = new object();
private static Semaphore _pool;
private static Semaphore pool
{
get
{
if (_pool == null)
lock (poolLocker)
if (_pool == null)
{
int count = myMaximumThreadCount;
_pool = new Semaphore(count, count);
}
return _pool;
}
}
private void run()
{
try
{
pool.WaitOne();
do_something_that_may_throw_exception();
}
finally
{
try
{
pool.Release();
}
catch (SemaphoreFullException) { }
}
}
Try to change the initialization of the semaphore object in pool property to:
private static Semaphore pool
{
get
{
if (_pool == null)
lock (poolLocker)
if (_pool == null)
{
int count = myMaximumThreadCount;
_pool = new Semaphore(0, count);
}
return _pool;
}
}
An initial count for this semaphore should be set to zero.
I have found the cause of the deadlock; and it has nothing to do with the question I've asked, so this is a bad question, sorry for that. There seems to be no problem in the code in the question.
The cause: In the do_something_that_may_throw_exception() function, an extern function of a C++ library is being called. When an error occurs in the C++ function, a SEHException is thrown. However, in my tries this exception can only be caught in a function that has HandleProcessCorruptedStateExceptions and SecurityCritical attributes. And that function happens to call the run() function of the question. However, the finally part of the run() function is newer executed! Also, if you have a using(IDisposable object){ ... } and the SEHException occurs inside it; object's Dispose() function won't be called.
I've used the following function for calling the C++ function; and everything worked fine:
SafeCall(()=> call_external_cpp_function());
[HandleProcessCorruptedStateExceptions]
[SecurityCritical]
internal static void SafeCall(Action action)
{
try
{
action();
}
catch (System.Threading.ThreadAbortException) { throw; }
catch (System.Threading.ThreadInterruptedException) { throw; }
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
I would like ask you to explain me how the exception system works in the following piece of code:
static void Main(string[] args)
{
try
{
//Code which throws exceptions from time to time and runs in a loop
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
Console.ReadKey();
}
I noticed something which surprised me. When an exception is thrown, the code inside try{...} block is still running and can throw even more exceptions which will be printed to the console window.
Shouldn't the code inside the loop finish its execution and "jump" to Console.ReadKey() at the end?
#EDIT:
The code inside is complicated and it would take a few pages. I can tell you that I make multiple asynchronous operations inside like downloading files, receiving packets, etc. In other words there are other threads which are created in the loop.
#EDIT2:
Presumably this is the code responsible for the behavior:
public SomeConstructor(Socket server)
{
_pb = new PacketBuilder(server, c);
SocketWrapper sw = new SocketWrapper(server, Globals.recvBufferSize);
sw.Socket.BeginReceive(sw.Buffer, 0, Globals.recvBufferSize, SocketFlags.None,PacketReceiveCallback, sw);
_pi = new PacketInterpreter(this, c);
}
private void PacketReceiveCallback(IAsyncResult iar)
{
SocketWrapper sw = iar.AsyncState as SocketWrapper;
int bytesReceived = sw.Socket.EndReceive(iar);
_pi.Interpret(sw.Buffer, 0, bytesReceived);
if (bytesReceived > 0)
sw.Socket.BeginReceive(sw.Buffer, 0, Globals.recvBufferSize, SocketFlags.None, PacketReceiveCallback, sw);
}
Code inside try block will execute as long as it doesn't throw an exception. If the exception throw within your try block the following code will not execute and it will jump to catch block.
static void Main(string[] args)
{
try
{
//Code which throws exceptions from time to time and runs in a loop
Console.WriteLine("Line 1");
throw new Exception("Sample Exception"); // your code will stop here and following line will not prine.
Console.WriteLine("This line will not print");
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
Console.ReadKey();
}
The only reason I can think of why you would get such a behavior is if you're starting new threads inside your try block. So if you're starting any new threads or using the task parallell library or plinq, you might get something like that.
But it's really hard to inspection-debug code that was replaced by a comment...
I am creating this windows service by following the instructions at MSDN Walkthrough: Creating a Windows Service and after successful installation, I go to Services.msc to Start the Windows service and before it finishes starting up I get the following message:
The EIWindowsService service on Local Computer started and then stopped. Some services stop automatically if they are not in use by other services or programs.
I know the Windows Service starts ok because there is an entry to the log file stating that the service started. I did some research before posting on here and the answer from Some Services Stop Automatically states that the problem could either be that the OnStart method is throwing an error, or that the OnStart is not kicking off a thread. So I modified my code so that the only thing within the OnStart is the starting of two timers and the log entry therefore needing no exception handling. I also added a thread to "jump" to another method.
I tried the windows service again and I know that it "moved" to the new method that the thread pointed to because I had a log entry in there that threw aFormatException error due to some conversion I was doing. I commented out the conversion and the windows service still just began to start up and then stopped automatically.
Further research indicated to me that I might need a loop to keep the processing within the method, so I took information from C - Windows Service the service on and set up an infinite while loop. I also found that there might be Garbage Collection going on and established a KeepAlive statement for the timers as suggested in Examples section of MSDN Timer Class. Still the same issues.
At this point I feel I've exhaused all the research I can do so it would be appropriate to post my question here. All my code is below and I will note that before I performed any change I uninstalled the Windows Service, removed the Setup Project, and deleted the installers from the C# code. I then made changes and started back over with the instructions in the Walkthrough starting at the point where it instructs how to setup the installers. I did this each time because I found that if I made changes and did not uninstall the Windows Service, remove the Setup Project, and delete the installers, then my changes would not take effect on the currently installed windows service.
Any assistance you can give would be most appreciated. I will be here for another 15min and then I will check this first thing tomorrow.
SERVICE1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Timers;
namespace EIWindowsService
{
public partial class Service1 : ServiceBase
{
Logs.ErrorLog logFile = new Logs.ErrorLog();
private System.Threading.Thread onStartThread;
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
try
{
iTimer.Start();
iTimer.Elapsed += new ElapsedEventHandler(iTimer_Elapsed);
pTimer.Start();
pTimer.Elapsed += new ElapsedEventHandler(pTimer_Elapsed);
onStartThread = new System.Threading.Thread(TimerValue);
onStartThread.Start();
logFile.SendToLog("EIWindows Service started on " + GetDate());
}
catch (ArgumentOutOfRangeException ex)
{
logFile.SendToLog("ArgumentOutOfRangeException", "EIWindowsService\\Service1.cs", "OnStart()", ex);
} //end of ArgumentOutOfRangeException CATCH statement
}
protected override void OnStop()
{
iTimer.Stop();
pTimer.Stop();
logFile.SendToLog("EIWindowsService\\Service1.cs", "OnStop()", "EIWindows Service stopped on " + GetDate());
}
private void TimerValue()
{
try
{
/*commented out because it was throwing an exception error*/
//double iTimerValue = Convert.ToDouble(iTimer.ToString());
//double pTimerValue = Convert.ToDouble(pTimer.ToString());
while (1 > 0)
{
//if (iTimerValue % 1800000 == 0) //if the timer hits the 30min mark
//{
// logFile.SendToLog("Current iTimer Value = " + iTimerValue.ToString());
//}
//if (pTimerValue % 1800000 == 0) //if the timer hits the 30min mark
//{
// logFile.SendToLog("Current pTimer Value = " + pTimerValue.ToString());
//}
GC.KeepAlive(iTimer);
GC.KeepAlive(pTimer);
}
//TimerValue();
}
catch (OverflowException ex)
{
logFile.SendToLog("OverflowException", "EIWindowsService\\Service1.cs", "TimerValue()", ex);
} //end of OverflowException CATCH statement
catch (ArgumentException ex)
{
logFile.SendToLog("ArgumentException", "EIWindowsService\\Service1.cs", "TimerValue()", ex);
} //end of ArgumentException CATCH statement
catch (FormatException ex)
{
logFile.SendToLog("FormatException", "EIWindowsService\\Service1.cs", "TimerValue()", ex);
} //end of FormatException CATCH statement
}
private string GetDate()
{
string current = "No Date Recorded";
try
{
current = DateTime.Now.ToString("F");
}
catch (FormatException ex)
{
logFile.SendToLog("FormatException", "EIWindowsService\\Service1.cs", "GetDate()", ex);
} //end of FormatException CATCH statement
return current;
} //end of method GetDate
private void iTimer_Elapsed(object source, ElapsedEventArgs e)
{
try
{
iTimer.Stop();
ImportI();
iTimer.Start();
}
catch (ArgumentOutOfRangeException ex)
{
logFile.SendToLog("ArgumentOutOfRangeException", "EIWindowsService\\Service1.cs", "iTimer_Elapsed()", ex);
} //end of ArgumentOutOfRangeException CATCH statement
} //end of method iTimer_Elapsed
private void pTimer_Elapsed(object source, ElapsedEventArgs e)
{
try
{
pTimer.Stop();
ImportP();
pTimer.Start();
}
catch (ArgumentOutOfRangeException ex)
{
logFile.SendToLog("ArgumentOutOfRangeException", "EIWindowsService\\Service1.cs", "pTimer_Elapsed()", ex);
} //end of ArgumentOutOfRangeException CATCH statement
} //end of method pTimer_Elapsed
private void ImportI()
{
//does some action but commented out because it never gets here and is not relavant to this question.
} //end of method ImportI
private void ImportP()
{
//does some action but commented out because it never gets here and is not relavant to this question.
} //end of method ImportP
}
}
SERVICE1.DESIGNER.CS (the relavant stuff)
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.pTimer = new System.Timers.Timer(10800000); //3hrs
this.iTimer = new System.Timers.Timer(3600000); //1hr
//
// pTimer
//
this.pTimer.Enabled = true;
//
// iTimer
//
this.iTimer.Enabled = true;
//
// Service1
//
this.ServiceName = "EIWindowsService";
}
#endregion
private System.Timers.Timer pTimer;
private System.Timers.Timer iTimer;
You don't need to create a separate thread or worry about the garbage collector. The framework handles all that for you. Just create the timers and they will be called. Here's an example.
public partial class Service1 : ServiceBase
{
private Timer timer;
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
timer = new Timer(1000);
timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
timer.Start();
}
void timer_Elapsed(object sender, ElapsedEventArgs e)
{
using (StreamWriter writer = File.AppendText(#"C:\Users\alfonso\Desktop\log.txt"))
{
writer.WriteLine(string.Format("{0} : {1}", DateTime.Now, "Logging from the service"));
}
}
protected override void OnStop()
{
}
}
Something else that may help someone coming across this post and the above solutions do not work. When I had this problem, I had added this to the config of my Windows Service:
<system.web>
<compilation debug ="true" />
</system.web>
I added this so that I could attach the debugger to the service when running it locally, however when I tried to move the service to another server it gave the specified error. By removing this from the config the service worked again.
This is difficult situation to explain. Have a service process that starts 2 threads, each thread loops forever but sleeps for 5 minutes each once the payload is finished.
Problem is that my second thread terminates well before the payload is even finished, for no apparent reason, and i also can't catch the exception as it seems to be triggered from outside the delegate process?
Any suggestions on how to find the problem?
The code....
public void StartService()
{
ThreadStart stRecieve = new ThreadStart(DownloadNewMail);
ThreadStart stSend = new ThreadStart(SendNewMail);
senderThread = new Thread(stRecieve);
recieverThread = new Thread(stSend);
sendStarted = true;
recieveStarted = true;
senderThread.Start();
recieverThread.Start();
}
private void DownloadNewMail()
{
while(recieveStarted)
{
//Payload....
if (recieveStarted)
{
Thread.Sleep(new TimeSpan(0, confSettings.PollInterval, 0));
}
}
}
private void SendNewMail()
{
while(sendStarted)
{
//Payload....
if (sendStarted)
{
Thread.Sleep(new TimeSpan(0, confSettings.PollInterval, 0));
}
}
}
Try to check callstack lenght in your code:
class Program
{
static void Main(string[] args)
{
try
{
Hop();
}
catch (Exception e)
{
Console.WriteLine("Exception - {0}", e);
}
}
static void Hop()
{
CheckStackTrace();
Hip();
}
static void Hip()
{
CheckStackTrace();
Hop();
}
static void CheckStackTrace()
{
StackTrace s = new StackTrace();
if (s.FrameCount > 50)
throw new Exception("Big stack!!!!");
}
}
If you are having trouble following the flow of your application's code execution, try logging the entrance of methods with a timestamp and threadid.
Also, You can't catch the exception because it is a StackOverflowException.
See msdn: "Starting with the .NET Framework version 2.0, a StackOverflowException object cannot be caught by a try-catch block and the corresponding process is terminated by default. Consequently, users are advised to write their code to detect and prevent a stack overflow. For example, if your application depends on recursion, use a counter or a state condition to terminate the recursive loop. "
Do you utlize any heavy-weight library for tasks like DownloadNewMail and SendNewMail? For example I encountered StackOverflows when running large jobs using Microsoft.SqlServer.Dts.Runtime.Package. Try running the same workload sequentially inside a command-line application to see if the issue persists.