We have windows service which is running fine untill any exceptions occured in the process.
It contains two Threads
(GenerateInvoice and GenerateReport).
These threads are getting blocked and results in DeadLock like situation mostly when there is high CPU usage on our DataBase server.
We have done some changes in code to handle such situations like added while condition below code but still it is not working.
Below is the OnStart()
method of service:
protected override void OnStart(string[] args)
{
try
{
log.Debug("Starting Invoice Generation Service");
_thread = new Thread(new ThreadStart((new GenerateInvoice()).Process));
_thread.IsBackground = true;
_thread.Start();
_reportThread = new Thread(new ThreadStart((new GenerateReport()).Process));
_reportThread.IsBackground = true;
_reportThread.Start();
}
catch (Exception ex)
{
log.Error("Error in Invoice Generation Service:", ex);
}
}
Here is the processing code of first thread: GenerateInvoice
public void Process()
{
while (isProcessActive)
{
try
{
DBBilling obj = new DBBilling();
DataTable dtInvoiceID = obj.readData(@"SELECT * FROM (SELECT ird.BillByType, ird.InvoiceID, ir.BeginDate, ir.EndDate, ir.SendToQB, ir.SendEmail,
i.ARAccountID, i.ARAccountHotelID, i.invoiceNumber,i.[STATUS],UPDATETIME,row_number() over (PARTITION BY ird.INVOICEID ORDER BY UPDATETIME DESC) AS row_number
FROM Invoices i JOIN InvoicesRunRequestDetails ird ON ird.InvoiceID=i.InvoiceID
JOIN InvoicesRunRequest ir ON ird.RequestID = ir.RequestID
Where i.[STATUS] = 'PENDING') AS rows
WHERE ROW_NUMBER=1 ORDER BY UPDATETIME");
processCounter = 0;
#region process
if (dtInvoiceID != null && dtInvoiceID.Rows.Count > 0)
{
//some code here..
}
#endregion
}
catch (Exception ex) //Mantis 1486 : WEBPMS1 Disk Space : 10 Aug 2016
{
log.ErrorFormat("Generate Invoice -> Process -> InnLink Billing Execute Query Exception. Error={0}", ex);
if(DBBilling.dbConnTimeoutErrorMessage.Any(ex.Message.Contains))
{
processCounter++;
if (processCounter >= 1) //Need to change to 25 after Problem Solve
{
isProcessActive = false;
log.ErrorFormat("Generate Invoice -> Process -> RunInvoice Service exiting loop"); //From here control is not going back
}
else
System.Threading.Thread.Sleep(5000); //Sleep for 5 Sec
}
}
}
}
Processing of Second Thread i.e. GenerateReport code:
public void Process()
{
AppSettingsReader ar = new AppSettingsReader();
string constr = (string)ar.GetValue("BillingDB", typeof(string));
SqlConnection con = new SqlConnection(constr);
while (isProcessActive)
{
try
{
DBBilling obj = new DBBilling();
DataTable dtReportRunID = obj.readData(@"SELECT ReportRunID,MonYear, BeginDate, EndDate FROM ReportRunRequest
Where [STATUS] = 'PENDING' ORDER BY ReportRunID");
processCounter = 0;
if (dtReportRunID != null && dtReportRunID.Rows.Count > 0)
{
//some code here..
}
}
catch (Exception ex) //Mantis 1486 : WEBPMS1 Disk Space : 10 Aug 2016
{
log.ErrorFormat("Generate Report -> Process -> InnLink Billing Execute Query Exception. Error={0}", ex);
if (DBBilling.dbConnTimeoutErrorMessage.Any(ex.Message.Contains))
{
processCounter++;
if (processCounter >= 1) //Need to change to 25 after Problem Solve
{
isProcessActive = false;
log.ErrorFormat("Generate Report -> Process -> RunInvoice Service Exiting loop"); //From here control is not going back
}
else
System.Threading.Thread.Sleep(5000); //Sleep for 5 Sec
}
}
}
}
What possible solution to avoid such conditions?