This IfxTransaction has completed; it is no longer usable - c#

Q:
When I use the transactions ,I'll get the following error on about 1 out of every 100 record.
This IfxTransaction has completed; it
is no longer usable
I can't expect when the error happen or what is the reason of this error.
I try to insert about 607 record in the same transaction.
My code:
public static int InsertGroups(List<Group> groups)
{
DBConnectionForInformix con = new DBConnectionForInformix("");
con.Open_Connection();
con.Begin_Transaction();
int affectedRow = -1;
Dictionary<string, string> groupsParameter = new Dictionary<string, string>();
try
{
foreach (Group a in groups)
{
groupsParameter.Add("id", a.GroupId.ToString());
groupsParameter.Add("name", a.Name);
groupsParameter.Add("studentcount", a.StudentCount.ToString());
groupsParameter.Add("divisiontag", a.DivisionTag.ToString());
groupsParameter.Add("entireclass", a.EntireClass.ToString());
groupsParameter.Add("classid", a.ClassId.ToString());
groupsParameter.Add("depcode", a.DepCode.ToString());
groupsParameter.Add("studycode", a.StudyCode.ToString());
groupsParameter.Add("batchnum", a.BatchNum.ToString());
affectedRow = DBUtilities.InsertEntityWithTrans("groups", groupsParameter, con);
groupsParameter.Clear();
if (affectedRow < 0)
{
break;
}
}
if (affectedRow > 0)
{
con.current_trans.Commit();
}
}
catch (Exception ee)
{
string message = ee.Message;
}
con.Close_Connection();
return affectedRow;
}
public void Begin_Transaction()
{
if (this.connection.State == ConnectionState.Open)
{
this.current_trans = this.connection.BeginTransaction(IsolationLevel.Serializable);
}
}
public static int InsertEntityWithTrans(string tblName, Dictionary<string, string> dtParams, DBConnectionForInformix current_conn)
{
int Result = -1;
string[] field_names = new string[dtParams.Count];
dtParams.Keys.CopyTo(field_names, 0);
string[] field_values = new string[dtParams.Count];
string[] field_valuesParam = new string[dtParams.Count];
dtParams.Values.CopyTo(field_values, 0);
for (int i = 0; i < field_names.Length; i++)
{
field_valuesParam[i] = "?";
}
//----------------------------------------------------------------------------------------------------------------------------------------------
string insertCmd = #"INSERT INTO " + tblName + " (" + string.Join(",", field_names) + ") values (" + string.Join(",", field_valuesParam) + ")";
//----------------------------------------------------------------------------------------------------------------------------------------------
IfxCommand com = new IfxCommand(insertCmd);
for (int j = 0; j < field_names.Length; j++)
{
com.Parameters.Add("?", field_values[j]);
}
try
{
Result = current_conn.Execute_NonQueryWithTransaction(com);
if (current_conn.connectionState == ConnectionState.Open && Result > 0)//OK: logging
{
# region // Log Area
#endregion
}
}
catch (Exception ex)
{
throw;
}
return Result;
}
public int Execute_NonQueryWithTransaction(IfxCommand com)
{
string return_msg = "";
int return_val = -1;
Open_Connection();
com.Connection = this.connection;
com.Transaction = current_trans;
try
{
return_val = com.ExecuteNonQuery();
}
catch (IfxException ifxEx)// Handle IBM.data.informix : mostly catched
{
return_val = ifxEx.Errors[0].NativeError;
return_msg = return_val.ToString();
}
catch (Exception ex)// Handle all other exceptions.
{
return_msg = ex.Message;
}
finally
{
if (!string.IsNullOrEmpty(return_msg))//catch error
{
//rollback
current_trans.Rollback();
Close_Connection();
connectionstate = ConnectionState.Closed;
}
}
return return_val;
}

You seem to be handling errors and rolling back the transaction in two places (in Execute_NonQueryWithTransaction and in InsertGroups.
And the return from Execute_NonQueryWithTransaction is used both to return error codes and to return rows affected. But in InsertGroups it is checked purely as a rows affected.
Could you have an error code from Execute_NonQueryWithTransaction (so transaction rolled back) being treated as success (rows inserted) in InsertGroups and the commit then fails?
Overall the code needs significant cleanup:
A catch block to only throw is pointless and just adds noise.
Just use exceptions for error handling, all normal returns should indicate success.

Related

Thread abort in Window Service in C#

I have a window Service which converts the PDF file to html and it is running in 5 threads.
Each thread picks the record from database where status is 0.Once it picks the record from database we are making the status to 64 and making an entry in log file so that other thread should not pick the same record,after successful conversion we are making the status to 256 if any exception we are making the stratus to 128.
Some records are updated to 64 with out any entry in log and they are not even processed further.
Below is the Stored Procedure to pick the single record from database.
Create PROCEDURE [SGZ].[p_GetNextRequestForProcessing]
#InstanceId int
AS
BEGIN
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
set nocount on
Declare #RequestID bigint = null;
SET #RequestID= (
Select
TOP(1) RequestID
From
sgz.PDFTransformationQueue
Where
RequestStatusID=0
);
If (#RequestID is not null)
BEGIN
Begin Transaction;
Update
sgz.PDFTransformationQueue
SET
RequestStatusid=64,
ProcessedInstanceID =#InstanceId,
ProcessStartTime = getutcdate(),
ModifiedDate=getutcdate()
Where
RequestID=#RequestID and
RequestStatusid =0 and
ProcessedInstanceID is null;
if ##rowcount = 0
set #RequestID=null;
Commit Transaction;
END
Select
RQ.VersionNumber,RQ.RequestID, RP.Payload
From
SGZ.RequestPayload RP WITH (NOLOCK),
SGZ.PDFTransformationQueue RQ WITH (NOLOCK)
Where
RP.RequestId=RQ.RequestID AND
ProcessedInstanceID=#InstanceId AND
RequestStatusid =64 AND
RQ.RequestId = #RequestID;
END
And below is the window service code:-
protected override void OnStart(string[] args)
{
PDFTransAutoProcessManager pdfTransAutoProcessManager = new
PDFTransAutoProcessManager();
pdfTransAutoProcessManager.OnProcessStart();
}
And PDFTransAutoProcessManager class:-
private int _runningAsyncThread = 0;
private int _totalAsynThread = 5;
public void OnProcessStart()
{
_logMgr.Info("Process started # " + DateTime.Now);
mainThread = new Thread(new ThreadStart(StartAutoProcess));
mainThread.Priority = ThreadPriority.Highest;
mainThread.Start();
}
private void StartAutoProcess()
{
try
{
while (true)
{
if (_runningAsyncThread < _totalAsynThread)
{
Thread childThread = new Thread(() => ProcessAsync());
Interlocked.Increment(ref _runningAsyncThread);
childThread.Start();
}
Thread.Sleep(100);
}
}
catch (Exception ex)
{ }
}
private void ProcessAsync()
{
try
{
PDFGenieManager pdfGenieManager = new
PDFGenieManager(_logMgr,gmi);
pdfGenieManager.ProcessRawData();
}
catch (Exception ex)
{
_logMgr.Info(ex.Message);
_logMgr.Info(ex.StackTrace);
}
finally
{
Interlocked.Decrement(ref _runningAsyncThread);
}
}
And in PDFGenieManager Class actual database call and conversion will happen.
When it is trying to get records from database some records are updated to 64 with out any entry in log.
Is it related to threading pattern or any problem with stored procedure.
Kindly help thanks in advance.
Below is the PDFGenieManager class code:-
namespace PDFConvertion
{
public class PDFGenieManager
{
public Logger _logMgr;
public GmiManager _gmi;
string _environment;
static readonly object _object = new object();
Dictionary<string, string> _ResourceMetadata = new Dictionary<string, string>();
public PDFGenieManager(Logger logMgr, GmiManager gmi)
{
_logMgr = logMgr;
_gmi = gmi;
_environment = ConfigurationManager.AppSettings["Envoirnment"];
}
public void ProcessRawData()
{
try
{
string unlockKey = string.Empty;
string languageRepair = string.Empty;
bool IsUnicodeRepair = false;
double confidenceScore = 1.0;
var Vendor = string.Empty;
string hiddenText = string.Empty;
DataTable rawData = new DataTable();
RuntimeCacheMgr _runtimeCacheMgr = new RuntimeCacheMgr();
DAL dal = new DAL();
try
{
rawData = dal.GetRawData();
if (rawData != null && rawData.Rows.Count > 0)
{
_logMgr.Info("Picked the record from datbase" + rawData.Rows[0]["Payload"].ToString());
}
if (!_runtimeCacheMgr.Exists(_environment))
{
_ResourceMetadata = dal.getResourcemetaDataValue(_environment);
_runtimeCacheMgr.Add(_environment, _ResourceMetadata);
}
else
{
_ResourceMetadata = _runtimeCacheMgr.Get<Dictionary<string, string>>(_environment);
}
}
catch (SqlException exe)
{
_logMgr.Error("Sql Database Error While Picking the records from database" + exe.Message + exe.StackTrace, exe.InnerException);
}
catch (Exception ex)
{
if (ex != null && !ex.ToString().ToLower().Contains("already exist"))
{
if (rawData != null && rawData.Rows.Count > 0)
{
_logMgr.Error("Exception block Picked the record from datbase" + rawData.Rows[0]["Payload"].ToString());
}
_logMgr.Error("Exception block" + ex.Message);
return;
}
else
{
if (rawData != null && rawData.Rows.Count > 0)
{
_logMgr.Error("Cache block Picked the record from datbase" + rawData.Rows[0]["Payload"].ToString());
}
_logMgr.Error("Cache block" + ex.Message + "" + ex.StackTrace);
}
}
finally
{
if (rawData != null && rawData.Rows.Count > 0)
{
_logMgr.Info("Finally block Picked the record from datbase" + rawData.Rows[0]["Payload"].ToString());
}
}
List<PDFGenieTran> ids = new List<PDFGenieTran>(rawData.Rows.Count);
rawData.AsEnumerable().ToList().ForEach(row => ids.Add(new PDFGenieTran() { Payload = row["Payload"].ToString(), RequestID = Convert.ToInt64(row["RequestID"]), VersionNumber = row["VersionNumber"].ToString() }));
PDFNetStatus PDFstatus = new PDFNetStatus();
foreach (PDFGenieTran pdf in ids)
{
}

Collection was modified; enumeration operation might not execute in LinQ

I get data from a site and insert to DataTable dt.
if (checked = true)
{
while (true)
{
breakIt = true;
try
{
string html = browser_array[idx].FindElementByXPath("id('tabbox')").GetAttribute("outerHTML");
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(html);
HtmlNodeCollection nodesMatchingXPathlop = doc.DocumentNode.SelectNodes("//*[contains(#class,'tabbox_F')]/table/tbody/tr");
if (nodesMatchingXPathlop.Count == 0)
{
break;
}
else
{
for (int j = 0; j < nodesMatchingXPathlop.Count; j++)
{
try
{
listHeader[1].Clear();
HtmlNodeCollection listTD3 = nodesMatchingXPathlop[j].SelectNodes("td");
if (nodesMatchingXPathlop[j].SelectNodes("td").ToString() == "")
return;
if (nodesMatchingXPathlop[j].SelectNodes("td").Count == 10)
{
if (listHeader[1].Count == 0)
continue;
else
Insert(dt, listHeader[1]);
}
else
{
continue;
}
}
catch (Exception ex) { throw; }
}
}
if (breakIt)
{
break;
}
}
catch (Exception ex) { throw; }
}
}
So, this function is Insert(DataTable dt, List<String> listHeader):
static void Insert(DataTable dt, List<String> listHeader)
{
DataRow row = dt.NewRow();
string[] array = listHeader.ToArray();
string newArray = "";
newArray = Regex.Replace(array[1], #"\s+", " ");
string arrayHindiCap2 = "";
arrayHindiCap2 = Regex.Replace(array[2], #"\s+", " ").Replace(" ", "");
string arrayHindiCap5 = "";
arrayHindiCap5 = Regex.Replace(array[5], #"\s+", " ").Replace(" ", "");
try
{
if (!string.IsNullOrWhiteSpace(arrayHindiCap2))
{
InsertCondition(arrayHindiCap2, arrayHindiCap5, newArray, listHeader, array);
}
else if (!string.IsNullOrWhiteSpace(arrayHindiCap5))
{
InsertCondition(arrayHindiCap2, arrayHindiCap5, newArray, listHeader, array);
}
}
catch (Exception ex) { throw; }
}
I have a table like this:
Option B0_1 Col 1 Col 2
op1 10 89
I will get an index of rows in DataTable when it correct with a condition.
static void InsertCondition(string arrayHindiCap2, string arrayHindiCap5, string newArray, List<String> listHeader, string[] array)
{
try
{
index = dt.AsEnumerable()
.Select((rowF, idx) => new { rowF, idx })
.Where(item =>
GetFirstB(numB) == (item.rowF.Field<string>("B0_1") != null ? item.rowF.Field<string>("B0_1") : "") &&
GetFirstWord(optionString) == (item.rowF.Field<string>("Option") != null ? item.rowF.Field<string>("Option") : ""))
.Select(item => item.idx)
.ToArray();
}
catch(Exception ex) { throw; }
}
I define GetFirstB() and GetFirstWord():
private static string GetFirstWord(string str)
{
try
{
return string.Concat(str.Split(' ').Take(2));
}
catch (Exception ex) { throw; }
}
private static string GetFirstB(string str)
{
try
{
if (str == null)
return null;
if (str.Equals(" "))
return null;
string[] strNew;
strNew = str.Split(' ');
strNew = strNew.Where(c => c != "").ToArray();
return string.Concat(strNew.FirstOrDefault());
}
catch (Exception ex) { throw; }
}
Following #ScottChamberlain and #PhilipKendall suggest.
I edit my code and tried debug again.
After Copy exception copies detail to clipboard it shows like this:
System.InvalidOperationException was caught
HResult=-2146233079
Message=Collection was modified; enumeration operation might not execute.
Source=System.Data
StackTrace:
at System.Data.RBTree`1.RBTreeEnumerator.MoveNext()
at System.Linq.Enumerable.<CastIterator>d__b1`1.MoveNext()
at System.Linq.Enumerable.<SelectIterator>d__7`2.MoveNext()
at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
at LAPSOFT.Program.InsertCondition(String arrayHindiCap2, String arrayHindiCap5, String newArray, List`1 listHeader, String[] array) in d:\lapsoft-project\CA CUOC - Copy\Program.cs:line 418
at LAPSOFT.Program.Insert(DataTable dt, List`1 listHeader) in d:\project\CheckCopy\Program.cs:line 548
InnerException:

Thread started by windows service stops without error and yet it supposed to run an infinite loop

I am trying to create a windows service that calls a thread in a library. This is all in c#. The library has a function that reads from an oracle database, processes the data, stores it in a SQL Server database and updates the records in the oracle database. I run tests on this and saw that the loop runs about 80,000 times and then without throwing any errors (i even checked the event log) nothing happens. Please help with this
This is the code
Windows Service
protected override void OnStart(string[] args)
{
try
{
base.OnStart(args);
controller = new BillingController();
thread = new Thread(new ThreadStart(controller.dowork));
thread.Start();
AppLogs.LogtoFile("SmartCDRBillingService.log", string.Format("SmartCDRBillingService started successfully"));
}
catch (Exception ex)
{
AppLogs.LogtoFile("SmartCDRBillingService.log", string.Format("Start Service error: {0}: {1}:", ex.Message.ToString(), ex.InnerException));
}
}
Controller
public BillingController()
{
AppConfig.LoadSettings();
}
public void dowork()
{
try
{
BillingQueue nLogic = new BillingQueue();
nLogic.QueueWorkItems();
}
catch (Exception ex)
{
//log
AppLogs.LogtoFile("BillingController.log", string.Format("dowork error: {0}: {1}:", ex.Message.ToString(), ex.InnerException));
}
}
Queue
public void QueueWorkItems()
{
new System.Threading.Thread(new System.Threading.ThreadStart(doQueueWork)).Start();
}
private void doQueueWork()
{
counter = 1;
while (true)
{
counter++;
List<EventUsageObject> eList = new List<EventUsageObject>();
try
{
eList = _osqlcon.getallusageevents();
if (eList.Count == 0)
{
continue;
}
else
{
ProcessUsageRequest(eList);//for Event Usage
}
}
catch (Exception ex)
{
//log the error
AppLogs.LogtoFile("BillingQueue.log", string.Format("doQueueWork error: {0}: {1}:", ex.Message.ToString(), ex.InnerException));
}
}
}
public List<EventUsageObject> getallusageevents()
{
List<EventUsageObject> recobjec = new List<EventUsageObject>();
OracleConnection conn = new OracleConnection();
try
{
conn.ConnectionString = osql.getOracleConnectionString();
conn.Open();
OracleCommand command = conn.CreateCommand();
command.CommandType = CommandType.StoredProcedure;
string query = "SMART_DWH_OBJECT.GETALLEVENTSUSAGE";
command.CommandText = query;
OracleParameter myParameter = new OracleParameter("rc", OracleDbType.RefCursor);
command.Parameters.Add("OUT_DATA", OracleDbType.RefCursor).Direction = ParameterDirection.Output;
using (OracleDataReader reader = command.ExecuteReader(CommandBehavior.CloseConnection))
{
reader.FetchSize = 10000;
while (reader.Read())
{
try
{
EventUsageObject info = new EventUsageObject();
info.CallStart = Convert.ToDateTime(reader["E_TIME"].ToString());
info.CallingMsisdn = reader["ACC_NBR"].ToString();
info.CalledMsisdn = reader["CALLED_MSISDN"].ToString();
info.Re_Id = Convert.ToInt32(reader["RE_ID"].ToString());
info.EventName = reader["EVENT_NAME"].ToString();
info.Duration = Convert.ToInt32(reader["DURATION"].ToString());
info.Duration2 = Convert.ToInt32(reader["DURATION2"].ToString());
info.Duration3 = Convert.ToInt32(reader["DURATION3"].ToString());
info.Duration4 = Convert.ToInt32(reader["DURATION4"].ToString());
info.Uplink = Convert.ToInt32(reader["UPLINK"].ToString());
info.Downlink = Convert.ToInt32(reader["DOWNLINK"].ToString());
info.PriceList = reader["PRICE_LIST"].ToString();
info.Cell_A = reader["CELL_A"].ToString();
info.Cell_B = reader["CELL_B"].ToString();
info.Acct_item_Type_Id1 = Convert.ToInt32(reader["ACCT_ITEM_TYPE_ID1"].ToString());
info.Acct_item_Type_Id2 = Convert.ToInt32(reader["ACCT_ITEM_TYPE_ID2"].ToString());
info.Acct_item_Type_Id3 = Convert.ToInt32(reader["ACCT_ITEM_TYPE_ID3"].ToString());
info.Acct_item_Type_Id4 = Convert.ToInt32(reader["ACCT_ITEM_TYPE_ID4"].ToString());
info.BalanceType1 = reader["BALANCE_TYPE1"].ToString();
info.BalanceType2 = reader["BALANCE_TYPE2"].ToString();
info.BalanceType3 = reader["BALANCE_TYPE3"].ToString();
info.BalanceType4 = reader["BALANCE_TYPE4"].ToString();
string d1 = reader["CHARGE1"].ToString();
string d2 = reader["CHARGE2"].ToString();
string d3 = reader["CHARGE3"].ToString();
string d4 = reader["CHARGE4"].ToString();
info.Charge1 = Convert.ToInt32(reader["CHARGE1"].ToString());
info.Charge2 = Convert.ToInt32(reader["CHARGE2"].ToString());
info.Charge3 = Convert.ToInt32(reader["CHARGE3"].ToString());
info.Charge4 = Convert.ToInt32(reader["CHARGE4"].ToString());
info.Prebalance1 = Convert.ToDouble(reader["PRE_BALANCE1"].ToString());
info.Prebalance2 = Convert.ToDouble(reader["PRE_BALANCE2"].ToString());
info.Prebalance3 = Convert.ToDouble(reader["PRE_BALANCE3"].ToString());
info.Prebalance4 = Convert.ToDouble(reader["PRE_BALANCE4"].ToString());
info.Recstatus = 0;
recobjec.Add(info);
}
catch (Exception ex)
{
continue;
}
}
}
conn.Close();
conn.Dispose();
}
catch (Exception ex)
{
AppLogs.LogtoFile("DBAPIError.log", string.Format("DBAPI error on getallusageevents error: {0}: {1}:", ex.Message.ToString(), ex.StackTrace));
}
return recobjec;
}
public void ProcessUsageRequest(List<EventUsageObject> list)
{
try
{
//log the eventusage into the database.
if (list.Count == 0)
//do nothing
return;
else
_mssqlcon.logEventUsage(list, _osqlcon);
}
catch (Exception ex)
{
AppLogs.LogtoFile("BillingQueue.log", string.Format("ProcessUsageRequest error on loggingeventusage: {0}: {1}:", ex.Message.ToString(), ex.InnerException));
}
}
public void logEventUsage(List<EventUsageObject> ilist, DBAPI osql)
{
int counter = 0;
try
{
foreach (EventUsageObject log in ilist)
{
try
{
counter++;
sql.executeNonQueryStoredProcedure("dbo.sp_dwh_eventusage", log.CallStart.ToString(), log.CallingMsisdn, log.CalledMsisdn, log.Re_Id.ToString(),
log.EventName.ToString(), log.Duration.ToString(), log.Duration2.ToString(), log.Duration3.ToString(),
log.Duration4.ToString(), log.Uplink.ToString(), log.Downlink.ToString(), log.PriceList, log.Cell_A,
log.Cell_B, log.Acct_item_Type_Id1.ToString(), log.Acct_item_Type_Id2.ToString(), log.Acct_item_Type_Id3.ToString(),
log.Acct_item_Type_Id4.ToString(), log.BalanceType1, log.Charge1.ToString(), log.BalanceType2, log.Charge2.ToString(),
log.BalanceType3, log.Charge3.ToString(), log.BalanceType4, log.Charge4.ToString(), log.Recstatus.ToString(), log.Prebalance1.ToString(),
log.Prebalance2.ToString(), log.Prebalance3.ToString(), log.Prebalance4.ToString());
string query = "UPDATE dwh_ug_eventusage SET recstatus = 1" +
" WHERE E_TIME = TO_DATE('" + log.CallStart + "', 'MM/DD/YYYY HH:MI:SS PM') AND ACC_NBR = '" + log.CallingMsisdn + "'";
osql.executeNonQueryText(query);
AppLogs.LogtoFile("BillingQueue.log",
string.Format("ProcesssubscriptionRequest has processed: {0} record",
log.Msisdn));
}
catch (SqlException ex)
{
if (ex.Number == 2601)
{
string query = "UPDATE dwh_ug_eventusage SET recstatus = 1" +
" WHERE E_TIME = TO_DATE('" + log.CallStart + "', 'MM/DD/YYYY HH:MI:SS PM') AND ACC_NBR = '" + log.CallingMsisdn + "'";
osql.executeNonQueryText(query);
}
AppLogs.LogtoFile("DBAPIError.log", string.Format("DBAPI error on logEventUsage: {0}: {1}:",
continue;
}
}
}
catch (Exception ex)
{
AppLogs.LogtoFile("DBAPIError.log", string.Format("DBAPI error on logEventUsage: {0}: {1}:",
ex.Message.ToString(), ex.StackTrace));
}
}

Sending Multiple Recepients in a single mail: Consequences

While sending email via System.Net.Mail to multiple recipients (one single email with multiple recipients), if one recipients address fail, will the rest reach the email?
There might be duplicates of the same question, but I'm asking something different in contrast.
For prompting such question, I was taken into consideration of Email clients available like Outlook where such does not happen even if one single address failed. Perhaps, System.Net.Mail is a lightweight client and does not allow such functionality? Or is it the way I'm writing my code incorrectly.
I was asked as if why this happens, hope I can get an explanation so that I can pass it by.
I was running such a scenario from my code below:
public void sendBusinessEmail(communication.email.business.config.BusinessEmailList[] aEmailList)
{
System.Net.Mail.MailMessage objMsg = null;
string[] aEmail = null;
System.Net.Mail.SmtpClient objSmtpClient = null;
int iRetries = 0;
if (aEmailList == null)
{
return;
}
try
{
if (Properties.Settings.Default.IS_SMTP_TLS)
{
objSmtpClient = getSMTP_TLS_Client();
ServicePointManager.ServerCertificateValidationCallback = delegate(object s, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; };
}
else
{
objSmtpClient = getSMTP_Default_Client();
}
foreach (communication.email.business.config.BusinessEmailList obj in aEmailList)
{
try
{
objMsg = new System.Net.Mail.MailMessage();
objMsg.From = new System.Net.Mail.MailAddress("jkstock#keells.com", "JKSB Business Services");
aEmail = obj.Emails;
if (Properties.Settings.Default.TO_TEST_EMAIL)
{
objMsg.To.Add(Properties.Settings.Default.TO_TEST_EMAIL_ADDRESS.ToString());
for (int i = 0; i < aEmail.Length; i++)
{
objMsg.Body += aEmail[i] + Environment.NewLine;
}
}
else
{
for (int i = 0; i < aEmail.Length; i++)
{
objMsg.To.Add(new System.Net.Mail.MailAddress(aEmail[i]));
}
objMsg.Body = obj.EmailBody;
}
objMsg.Subject = checkAllReadySent(obj.EmailSubject);
objMsg.Attachments.Add(new System.Net.Mail.Attachment(obj.AttachmentPath, (System.IO.Path.GetExtension(obj.AttachmentPath) == ".pdf" ? System.Net.Mime.MediaTypeNames.Application.Pdf : System.Net.Mime.MediaTypeNames.Application.Octet)));
//sending emails
//send for 5 times if error persists, unless otherwise success
for (int i = 0; i < 5; i++)
{
try
{
objSmtpClient.Send(objMsg);
obj.updateLog("OK", (i+1));
break;
}
catch (Exception e)
{
if (i == 4)
{
obj.updateLog(e.Message, (i+1));
}
}
}
objMsg = null;
}
catch (System.Net.Mail.SmtpFailedRecipientsException e0)
{
obj.updateLog("Invalid Recipient(s)",0);
}
catch (Exception e1)
{
obj.updateLog("Error",0);
}
}
objSmtpClient = null;
}
catch (Exception e2)
{
MessageBox.Show(e2.Message);
objMsg = null;
objSmtpClient = null;
}
}
References for the above code:
public abstract class BusinessEmailList
{
private string _accountid = string.Empty;
private string _attachmentPath = string.Empty;
private string _emailsubject = string.Empty;
private string _agentid = string.Empty;
private string _response = string.Empty;
private string _ccTo = string.Empty;
private string _bccTo = string.Empty;
protected string _additionalBody = string.Empty;
private string[] _aEmail = null;
public string AccountID
{
get { return _accountid; }
set { _accountid = value; }
}
public string AgentID
{
get { return _agentid; }
set { _agentid = value; }
}
public string Response
{
get { return _response; }
set { _response = value; }
}
public string AttachmentPath
{
get { return _attachmentPath; }
set
{
if (System.IO.File.Exists(value))
{
_attachmentPath = value;
}
else { throw (new Exception("Attachment Not Found")); }
}
}
public string EmailSubject
{
get { return _emailsubject; }
set { _emailsubject = value; }
}
public string[] Emails
{
get { return getEmail(); }
}
public string EmailBody
{
get { return getMsgBody(); }
set { _additionalBody = value; }
}
public string ccTo
{
get { return _ccTo; }
set { _ccTo = value; }
}
public string bccTo
{
get { return _bccTo; }
set { _bccTo = value; }
}
public virtual string[] getEmail()
{
return null;
}
public virtual string getMsgBody()
{
if (System.IO.Path.GetExtension(this.AttachmentPath) == ".pdf")
{
return "Dear Sir/Madam, " +
Environment.NewLine +
Environment.NewLine +
"With kind Reference to the above, details as per attachment." +
Environment.NewLine +
Environment.NewLine +
"To view the attached PDF files you need Adobe Acrobat Reader installed in your computer. Download Adobe Reader from http://get.adobe.com/reader/ " +
Environment.NewLine +
Environment.NewLine +
"Thank you," +
Environment.NewLine +
"John Keells Stock Brokers (Pvt) Ltd.";
}
else
{
return "Dear Sir/Madam, " +
Environment.NewLine +
Environment.NewLine +
"With kind Reference to the above, details as per attachment." +
Environment.NewLine +
Environment.NewLine +
"Thank you," +
Environment.NewLine +
"John Keells Stock Brokers (Pvt) Ltd.";
}
}
public void updateLog(string status, int retries)
{
try
{
using (OracleConnection oracleConn = new OracleConnection(EquityBroker32.Properties.Settings.Default.JKSB_CONN_ORA.ToString()))
{
OracleCommand cmd = new OracleCommand();
cmd.Connection = oracleConn;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "JKSBSCHEMA.EMAILLOG_ADD_PROC";
string[] aEmail = this.Emails;
OracleParameter p = null;
foreach (string s in aEmail)
{
cmd.Parameters.Clear();
p = new OracleParameter("pemail", OracleType.VarChar);
p.Value = s;
cmd.Parameters.Add(p);
p = new OracleParameter("psubject", OracleType.VarChar);
p.Value = this.EmailSubject;
cmd.Parameters.Add(p);
p = new OracleParameter("pattachement", OracleType.VarChar);
p.Value = this.AttachmentPath;
cmd.Parameters.Add(p);
p = new OracleParameter("presponse", OracleType.VarChar);
p.Value = status;
cmd.Parameters.Add(p);
p = new OracleParameter("pseqno", OracleType.Number);
p.Direction = ParameterDirection.InputOutput;
p.Value = "0";
cmd.Parameters.Add(p);
p = new OracleParameter("pretries", OracleType.Number);
p.Value = retries;
cmd.Parameters.Add(p);
oracleConn.Open();
cmd.ExecuteNonQuery();
oracleConn.Close();
}
}
}
catch (Exception er)
{
this.Response = er.Message;
}
}
}
public class BusinessClientEmailList : BusinessEmailList
{
public override string[] getEmail()
{
string[] aEmail;
//if (Properties.Settings.Default.TO_TEST_EMAIL == false)
//{
try
{
using (OracleConnection oracleConn = new OracleConnection(EquityBroker32.Properties.Settings.Default.JKSB_CONN_ORA.ToString()))
{
string sql = "SELECT EMAIL " +
"FROM " +
"(" +
"SELECT A.EMAIL AS EMAIL " +
"FROM JKSBSCHEMA.AGENTEMAIL A " +
"WHERE A.AGENTID = '" + this.AgentID + "' " +
"AND A.AGENTID != 'JKSB' "+
"AND A.ISACTIVE = 1 " +
"UNION " +
"SELECT B.EMAILID AS EMAIL " +
"FROM JKSBSCHEMA.CLIENTACCOUNTEMAIL B " +
"WHERE B.CLIENTACCOUNTID = '" + this.AccountID + "' " +
"AND B.IS_CONFIRMATION = 1 " +
") " +
"GROUP BY EMAIL";
int i = 0;
DataTable tbl = new DataTable();
OracleCommand cmd = new OracleCommand(sql, oracleConn);
cmd.CommandType = CommandType.Text;
OracleDataAdapter da = new OracleDataAdapter(cmd);
da.Fill(tbl);
aEmail = new string[tbl.Rows.Count];
foreach (DataRow rw in tbl.Rows)
{
aEmail[i] = rw[0].ToString();
i++;
}
}
}
catch (Exception)
{
aEmail = null;
}
//}
//else
//{
// aEmail = new string[1];
// aEmail[0] = Properties.Settings.Default.TO_TEST_EMAIL_ADDRESS.ToString();
//}
return aEmail;
}
public override string getMsgBody()
{
return base.getMsgBody();
}
}

Operation is not valid due to the current state of the object. in C#

I had created this method to check number of this record in the table
but it gives me this error message when the value of count(*) is 0
i use this library to connect oracle db
using Oracle.DataAccess.Client;
private int checkPort(int portID)
{
int intCount = 0;
try
{
OracleCommand oraCommand = new OracleCommand();
oraCommand.Connection = new DBManager().getConnection();
oraCommand.CommandText = "select count(*) as num from wireless_port_oid where port_id=:port_id";
oraCommand.Parameters.Add(":port_id", portID);
OracleDataReader Reader= oraCommand.ExecuteReader();
return intCount;
while (**Reader.Read()**)//it gives exception here
//The err Operation is not valid due to the current state of the object.
{
intCount =Convert.ToInt32(Reader[0]);
Reader.Close();
oraCommand.Connection.Close();
oraCommand = null;
if (intCount > 0)
{
return 1;
}
}
Reader.Close();
Reader.Dispose();
oraCommand.Connection.Close();
oraCommand.Connection.Dispose();
oraCommand.Dispose();
return 0;
}
catch (OracleException exception)
{
Console.WriteLine(exception.Message);
return 0;
}
}
You're closing the reader on Count = 0 and then trying to read it again in the while loop.
while (Reader.Read())//it gives exception here
//The err Operation is not valid due to the current state of the object.
{
intCount =Convert.ToInt32(Reader[0]);
Reader.Close();
oraCommand.Connection.Close();
oraCommand = null;
if (intCount > 0)
{
return 1;
}
// if intCOunt == 0 then what? loop again
}
But your code is not valid - I just noticed that you have a return intCount; just before the line you says has an error. I assume that that's just example typo.
I would refactor your code to take adavantage of C#'s using statement:
private int checkPort(int portID) {
string sql = "select count(*) as num from wireless_port_oid where port_id=:port_id";
int intCount = 0;
try {
using(OracleCommand oraCommand = new OracleCommand()) {
using(oraCommand.Connection = new DBManager().getConnection()) {
oraCommand.CommandText = sql;
oraCommand.Parameters.Add(":port_id", portID);
intCount = oraCommand.ExecuteScalar();
}
}
}
catch (OracleException exception) {
Console.WriteLine(exception.Message);
// may be you shouldn't return 0 here possibly throw;
}
return intCount;
}

Categories