I'm newbie in SQLITE and I'm currently using System.Data.SQLite.dll version 1.0.89.0 in a C# project.
My database contains a simple table 'files' with following columns:
[id] VARCHAR(50) NOT NULL
[chunk] INTEGER NOT NULL
[content] BLOB NOT NULL
[size] INTEGER NOT NULL
[date_ins] DATETIME NOT NULL
PRIMARY KEY(id,chunk)
I created a class (OfflineStorage) to add and retrieve files in this table as BLOBS.
Save method works ok, but Load generate an InvalidCastException on GetStream extended method.
public class OfflineStorage
{
private static string l_strConnectionTemplate = "Data Source={0};Version=3;Password=\"{1}\";";
private string l_strConnection;
private int SQLITE_MAX_BLOB_LENGTH;
private string l_strCreateTable = #"CREATE TABLE IF NOT EXISTS [files]" +
"( " +
" [id] VARCHAR(50) NOT NULL, " +
" [chunk] INTEGER NOT NULL, " +
" [content] BLOB NOT NULL, " +
" [size] INTEGER NOT NULL, " +
" [date_ins] DATETIME NOT NULL, " +
" PRIMARY KEY(id,chunk) " +
")";
private string l_strSelectQuery = #"SELECT chunk, content, size FROM files WHERE id = #id ORDER BY chunk";
private string l_strUpdateQuery = #"UPDATE files SET content = content || #new_content, size = size + #size WHERE id = #id AND chunk = #chunk";
private string l_strInsertQuery = #"INSERT INTO files(id, chunk, content, size, date_ins) VALUES(#id, #chunk, #new_content, #size, DATETIME('now'))";
public OfflineStorage(string strFilename, string strPassword = "")
{
SQLiteConnection l_objConnection = null;
if (!File.Exists(strFilename))
{
l_strConnection = string.Format(l_strConnectionTemplate, strFilename, "");
SQLiteConnection.CreateFile(strFilename);
l_objConnection = new SQLiteConnection(l_strConnection);
l_objConnection.SetPassword(strPassword);
l_objConnection.Close();
}
l_strConnection = string.Format(l_strConnectionTemplate, strFilename, strPassword);
l_objConnection = getConnection();
using (SQLiteCommand l_objCommand = new SQLiteCommand(l_strCreateTable, l_objConnection))
{
l_objCommand.ExecuteNonQuery();
}
SQLITE_MAX_BLOB_LENGTH = 1000000;
CloseConnection(l_objConnection);
}
private SQLiteConnection getConnection()
{
SQLiteConnection l_objConnection = null;
try
{
l_objConnection = new SQLiteConnection(l_strConnection);
l_objConnection.Open();
return l_objConnection;
}
catch (Exception ex)
{
CloseConnection(l_objConnection);
throw new OfflineStorageException("Local Service open db error.", ex);
}
}
private void CloseConnection(SQLiteConnection objConnection)
{
if (objConnection != null)
{
objConnection.Close();
objConnection = null;
}
}
public long Load(string strID, Stream objStream)
{
if (!objStream.CanWrite)
throw new NotSupportedException("Stream not writable.");
SQLiteConnection l_objConnection = getConnection();
// Columns Identifier (name of file)
SQLiteParameter l_objID = new SQLiteParameter("#id", DbType.String);
l_objID.Value = strID;
SQLiteCommand l_objCommand = new SQLiteCommand(l_strSelectQuery, l_objConnection);
l_objCommand.Parameters.Add(l_objID);
// Load File Records
SQLiteDataReader l_objReader;
try
{
l_objReader = l_objCommand.ExecuteReader();
}
catch (Exception ex)
{
CloseConnection(l_objConnection);
throw new OfflineStorageException("SQLite exception.", ex);
}
long l_lFileLength = 0; // Complete file length
int l_iDBChunk = -1; // Current chunk on database
int l_iChunk = 0; // Current 'sub chunk'
long l_lChunkLength = -1; // Current 'sub chunk' length
try
{
// For each record of current file selected by identifier
while (l_objReader.Read())
{
l_iDBChunk = l_objReader.GetInt32(0); // Chunk ID
l_lChunkLength = l_objReader.GetInt64(2); // Chunk size
Trace.Assert(l_iChunk == l_iDBChunk); // Compare expected Chunck with Database ID Chunk
l_lFileLength += l_objReader.GetStream(objStream, 1, l_lChunkLength); // Load chunk
l_iChunk++;
}
}
catch (Exception ex)
{
string l_strMessage = string.Format("SQLite exception on file {0}, DB chunk {1}: \n{2}", strID, l_iDBChunk, ex.Message);
throw new OfflineStorageException(l_strMessage, ex);
}
finally
{
l_objReader.Close();
l_objCommand.Dispose();
CloseConnection(l_objConnection);
}
if (l_iChunk < 1)
{
string l_strMessage = string.Format("File {0} not readed on db.", strID);
throw new OfflineStorageException(l_strMessage);
}
return l_lFileLength;
}
public void Save(string strID, Stream objStream, bool bOverwrite = false)
{
const int CHUNK_SIZE = 8 * 1024;
if (!objStream.CanRead)
throw new NotSupportedException("Stream not readable.");
long l_lOldPosition = objStream.Position;
SQLiteConnection l_objConnection = getConnection();
byte[] lar_byBuffer = new byte[CHUNK_SIZE];
SQLiteParameter l_objID = new SQLiteParameter("#id", DbType.String);
l_objID.Value = strID;
SQLiteParameter l_objContent = new SQLiteParameter("#new_content", DbType.Binary);
l_objContent.Value = lar_byBuffer;
SQLiteParameter l_objChunk = new SQLiteParameter("#chunk", DbType.Int32);
SQLiteParameter l_objSize = new SQLiteParameter("#size", DbType.Int32);
SQLiteCommand l_objCommand = new SQLiteCommand(l_strInsertQuery, l_objConnection);
l_objCommand.Parameters.Add(l_objID);
l_objCommand.Parameters.Add(l_objContent);
l_objCommand.Parameters.Add(l_objChunk);
l_objCommand.Parameters.Add(l_objSize);
int l_iReturn, l_lBytesRead;
int l_iChunk = 0; // Current 'sub chunk'
int l_iDBChunk = 0; // Current chunk on database
long l_lDBChunkLength = 0; // Current length of chunk
l_objChunk.Value = l_iDBChunk;
//Transaction
using (SQLiteTransaction l_objTransaction = l_objConnection.BeginTransaction())
{
// Read File from stream
while ((l_lBytesRead = objStream.Read(lar_byBuffer, 0, lar_byBuffer.Length)) > 0)
{
// Check for next Chunk
if ((l_lDBChunkLength + l_lBytesRead) >= SQLITE_MAX_BLOB_LENGTH)
{
l_objCommand.CommandText = l_strInsertQuery;
l_iChunk = 0; // reset 'sub chunk' counter
l_lDBChunkLength = 0; // reset chunk size
l_iDBChunk++; // increase chunk ID
l_objChunk.Value = l_iDBChunk;
}
l_lDBChunkLength += l_lBytesRead; // Increase length of chunk
l_objContent.Size = l_lBytesRead; // Length of Content field
l_objSize.Value = l_lBytesRead; // Chunk lenght (write on 'size' column)
#region WRITE
try
{
l_iReturn = l_objCommand.ExecuteNonQuery();
if (l_iChunk == 0)
{
l_objCommand.CommandText = l_strUpdateQuery;
}
}
catch (Exception ex)
{
l_objTransaction.Rollback();
CloseConnection(l_objConnection);
string l_strMessage = string.Format("SQLite exception on file {0}, DB chunk {1}, chunk {2}: \n{3}", strID, l_iDBChunk, l_iChunk, ex.Message);
throw new OfflineStorageException(l_strMessage, ex);
}
if (l_iReturn != 1)
{
l_objTransaction.Rollback();
CloseConnection(l_objConnection);
string l_strMessage = string.Format("DB chunk {1}, chunk {2} of file {0} not inserted on db.", strID, l_iDBChunk, l_iChunk);
throw new OfflineStorageException(l_strMessage);
}
#endregion WRITE
l_iChunk++;
}
l_objTransaction.Commit();
}
l_objCommand.Dispose();
CloseConnection(l_objConnection);
objStream.Position = l_lOldPosition;
}
}
DB Data Reader Extended class:
public static class DbDataReaderExtension
{
public static long GetStream(this DbDataReader objReader, System.IO.Stream objStream, int iIndex = 0, long lFileLength = -1)
{
const int CHUNK_SIZE = 7 * 1024;
byte[] lar_byBuffer = new byte[CHUNK_SIZE]; // Buffer
long l_lBytesRead; // Bytes readed from SQLite database column
long l_lFieldOffset = 0; // Field offset on database column
long l_lBytesRemainig = lFileLength;
while ((l_lBytesRead = objReader.GetBytes(iIndex, l_lFieldOffset, lar_byBuffer, 0, lar_byBuffer.Length)) > 0)
{
l_lFieldOffset += l_lBytesRead; // prepare next offset
if (l_lBytesRemainig > 0) // check if a FileLength was set
{
l_lBytesRemainig -= l_lBytesRead; // remove readed bytes
if (l_lBytesRemainig < 0) // Cut last bytes not valid if file is bigger than column size
l_lBytesRead += l_lBytesRemainig;
}
// write only valid bytes
objStream.Write(lar_byBuffer, 0, (int)l_lBytesRead);
}
return lFileLength < 0 ? l_lFieldOffset : lFileLength;
}
}
I found this exception is generated because ReadBytes method (SQLiteDataReader) call VerifyType
private TypeAffinity VerifyType(int i, DbType typ)
{
CheckClosed();
CheckValidRow();
TypeAffinity affinity = GetSQLiteType(i).Affinity;
switch (affinity)
{
...
case TypeAffinity.Text:
if (typ == DbType.SByte) return affinity;
if (typ == DbType.String) return affinity;
if (typ == DbType.SByte) return affinity;
if (typ == DbType.Guid) return affinity;
if (typ == DbType.DateTime) return affinity;
if (typ == DbType.Decimal) return affinity;
break;
case TypeAffinity.Blob:
...
}
throw new InvalidCastException();
}
In this function isn't expected that typ is equal to DbType.Binary and affinity is equal to TypeAffinity.Text.
Can anyone help me to understand this problem?
Thank you
ok, here's how i have added and retrieved blobs.
i suppose it all depends on whether the byte[] is a manageable size. This worked for small objects being serialized to the database.
use GetDataTable to get the data and then on the row in question extract the byte array with the following:
public byte[] getByteArray(DataRow row, int offset)
{
object blob = row[offset];
if (blob == null) return null;
byte[] arData = (byte[])blob;
return arData;
}
this is how i add them:
private System.Object syncLock = new System.Object();
public int ExecuteNonQueryWithBlob(string sql, string blobFieldName, byte[] blob)
{
lock (syncLock)
{
try
{
using (var c = new SQLiteConnection(dbConnection))
{
using (var cmd = new SQLiteCommand(sql, c))
{
cmd.Connection.Open();
cmd.Parameters.AddWithValue("#" + blobFieldName, blob);
return cmd.ExecuteNonQuery();
}
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
return 0;
}
}
}
public DataTable GetDataTable(string sql)
{
lock (syncLock)
{
try
{
DataTable dt = new DataTable();
using (var c = new SQLiteConnection(dbConnection))
{
c.Open();
using (SQLiteCommand cmd = new SQLiteCommand(sql, c))
{
using (SQLiteDataReader rdr = cmd.ExecuteReader())
{
dt.Load(rdr);
return dt;
}
}
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
return null;
}
}
}
Related
I'm using this code to modify a pdf tmeplate to add specific details to it,
private static byte[] GeneratePdfFromPdfFile(byte[] file, string landingPage, string code)
{
try
{
using (var ms = new MemoryStream())
{
using (var reader = new PdfReader(file))
{
using (var stamper = new PdfStamper(reader, ms))
{
string _embeddedURL = "http://" + landingPage + "/Default.aspx?code=" + code + "&m=" + eventCode18;
PdfAction act = new PdfAction(_embeddedURL);
stamper.Writer.SetOpenAction(act);
stamper.Close();
reader.Close();
return ms.ToArray();
}
}
}
}
catch(Exception ex)
{
File.WriteAllText(HttpRuntime.AppDomainAppPath + #"AttachmentException.txt", ex.Message + ex.StackTrace);
return null;
}
}
this Method is being called from this Method:
public static byte[] GenerateAttachment(AttachmentExtenstion type, string Contents, string FileName, string code, string landingPage, bool zipped, byte[] File = null)
{
byte[] finalVal = null;
try
{
switch (type)
{
case AttachmentExtenstion.PDF:
finalVal = GeneratePdfFromPdfFile(File, landingPage, code);
break;
case AttachmentExtenstion.WordX:
case AttachmentExtenstion.Word:
finalVal = GenerateWordFromDocFile(File, code, landingPage);
break;
case AttachmentExtenstion.HTML:
finalVal = GenerateHtmlFile(Contents, code, landingPage);
break;
}
return zipped ? _getZippedFile(finalVal, FileName) : finalVal;
}
catch(Exception ex)
{
return null;
}
}
and here is the main caller,
foreach (var item in Recipients)
{
//...
//....
item.EmailAttachment = AttachmentGeneratorEngine.GenerateAttachment(_type, "", item.AttachmentName, item.CMPRCode, _cmpTmp.LandingDomain, _cmpTmp.AttachmentZip.Value, _cmpTmp.getFirstAttachment(item.Language, item.DefaultLanguage));
}
The AttachmentGeneratorEngine.GenerateAttachment method is being called approx. 4k times, because I'm adding a specific PDF file from a PDF template for every element in my List.
recently I started having this exception:
Exception of type 'System.OutOfMemoryException' was thrown. at System.IO.MemoryStream.ToArray()
I already implemented IDisposible in the classes and and I made sure that all of them are being released.
Note: it was running before very smoothely and also I double checked the system's resources - 9 GB is used out of 16 GB, so I had enough memory available.
==========================================
Update:
Here is the code that loops through the list
public static bool ProcessGroupLaunch(string groupCode, int customerId, string UilangCode)
{
CampaignGroup cmpGList = GetCampaignGroup(groupCode, customerId, UilangCode)[0];
_campaigns = GetCampaigns(groupCode, customerId);
List<CampaignRecipientLib> Recipients = GetGroupRcipientsToLaunch(cmpGList.ID, customerId);
try
{
foreach (var item in _campaigns)
item.Details = GetCampaignDetails(item.CampaignId.Value, UilangCode);
Stopwatch stopWatch = new Stopwatch();
#region single-threaded ForEach
foreach (var item in Recipients)
{
CampaignLib _cmpTmp = _campaigns.FirstOrDefault(x => x.CampaignId.Value == item.CampaignId);
bool IncludeAttachment = _cmpTmp.IncludeAttachment ?? false;
bool IncludeAttachmentDoubleBarrel = _cmpTmp.IncludeAttachmentDoubleBarrel ?? false;
if (IncludeAttachment)
{
if (_cmpTmp.AttachmentExtension.ToLower().Equals("doc") || (_cmpTmp.AttachmentExtension.ToLower().Equals("docx")))
_type = AttachmentGeneratorEngine.AttachmentExtenstion.Word;
else if (_cmpTmp.AttachmentExtension.ToLower().Equals("ppt") || (_cmpTmp.AttachmentExtension.ToLower().Equals("pptx")))
_type = AttachmentGeneratorEngine.AttachmentExtenstion.PowePoint;
else if (_cmpTmp.AttachmentExtension.ToLower().Equals("xls") || (_cmpTmp.AttachmentExtension.ToLower().Equals("xlsx")))
_type = AttachmentGeneratorEngine.AttachmentExtenstion.Excel;
else if (_cmpTmp.AttachmentExtension.ToLower().Equals("pdf"))
_type = AttachmentGeneratorEngine.AttachmentExtenstion.PDF;
else if (_cmpTmp.AttachmentExtension.ToLower().Equals("html"))
_type = AttachmentGeneratorEngine.AttachmentExtenstion.HTML;
}
//set "recpient" details
item.EmailFrom = _cmpTmp.EmailFromPrefix + "#" + _cmpTmp.EmailFromDomain;
item.EmailBody = GetChangedPlaceHolders((_cmpTmp.getBodybyLangCode(string.IsNullOrEmpty(item.Language) ? item.DefaultLanguage : item.Language, item.DefaultLanguage)), item.ID, _cmpTmp.CustomerId.Value, _cmpTmp.CampaignId.Value);
if (item.EmailBody.Contains("[T-LandingPageLink]"))
{
//..
}
if (item.EmailBody.Contains("[T-FeedbackLink]"))
{
//..
}
if (item.EmailBody.Contains("src=\".."))
{
//..
}
//set flags to be used by the SMTP Queue and Scheduler
item.ReadyTobeSent = true;
item.PickupReady = false;
//add attachment to the recipient, if any.
if (IncludeAttachment)
{
item.AttachmentName = _cmpTmp.getAttachmentSubjectbyLangCode(string.IsNullOrEmpty(item.Language) ? item.DefaultLanguage : item.Language, item.DefaultLanguage) + "." + _cmpTmp.AttachmentExtension.ToLower();
try
{
if (_type == AttachmentGeneratorEngine.AttachmentExtenstion.PDF || _type == AttachmentGeneratorEngine.AttachmentExtenstion.WordX || _type == AttachmentGeneratorEngine.AttachmentExtenstion.Word)
item.EmailAttachment = AttachmentGeneratorEngine.GenerateAttachment(_type, "", item.AttachmentName, item.CMPRCode, _cmpTmp.LandingDomain, _cmpTmp.AttachmentZip.Value, _cmpTmp.getFirstAttachment(item.Language, item.DefaultLanguage));
else item.EmailAttachment = AttachmentGeneratorEngine.GenerateAttachment(_type, value, item.AttachmentName, item.CMPRCode, _cmpTmp.LandingDomain, _cmpTmp.AttachmentZip.Value);
item.AttachmentName = _cmpTmp.AttachmentZip.Value ? (_cmpTmp.getAttachmentSubjectbyLangCode(string.IsNullOrEmpty(item.Language) ? item.DefaultLanguage : item.Language, item.DefaultLanguage) + ".zip") :
_cmpTmp.getAttachmentSubjectbyLangCode(string.IsNullOrEmpty(item.Language) ? item.DefaultLanguage : item.Language, item.DefaultLanguage) + "." + _cmpTmp.AttachmentExtension.ToLower();
}
catch (Exception ex)
{
}
}
else
{
item.EmailAttachment = null;
item.AttachmentName = null;
}
}
#endregion
stopWatch.Stop();
bool res = WriteCampaignRecipientsLaunch(ref Recipients);
return res;
}
catch (Exception ex)
{
Recipients.ForEach(i => i.Dispose());
cmpGList.Dispose();
Recipients = null;
cmpGList = null;
return false;
}
finally
{
Recipients.ForEach(i => i.Dispose());
cmpGList.Dispose();
Recipients = null;
cmpGList = null;
}
}
Using .NET 4, wpf c#, I am passing method return values and parameters between two processes.
As I need the connection open and active a all times, I have tried my best to minimize the code that is recurring (within the loop) but unless I put this whole code inside the loop it did not succeed (after the first transfer the connection to server was closed), so as it is here, it does work repeatedly.
I was wondering first is this the way it should be coded, all the process including the new instance, dispose, close... within the loop?
Is the only available datatype for inter-process communication to pass as a string (inefficient)?
public void client()
{
for (int i = 0; i < 2; i++)
{
System.IO.Pipes.NamedPipeClientStream pipeClient =
new System.IO.Pipes.NamedPipeClientStream(".", "testpipe",
System.IO.Pipes.PipeDirection.InOut, System.IO.Pipes.PipeOptions.None);
if (pipeClient.IsConnected != true)
{
pipeClient.Connect(550);
}
System.IO.StreamReader sr = new System.IO.StreamReader(pipeClient);
System.IO.StreamWriter sw = new System.IO.StreamWriter(pipeClient);
string status;
status = sr.ReadLine();
if (status == "Waiting")
{
try
{
sw.WriteLine("param1fileName.cs,33" + i);
sw.Flush();
pipeClient.Close();
}
catch (Exception ex) { throw ex; }
}
}
}
public string server()
{
NamedPipeServerStream pipeServer = null;
do
{
try
{
pipeServer = new NamedPipeServerStream("testpipe", PipeDirection.InOut, 4);
StreamReader sr = new StreamReader(pipeServer);
StreamWriter sw = new StreamWriter(pipeServer);
System.Threading.Thread.Sleep(100);
pipeServer.WaitForConnection();
string test;
sw.WriteLine("Waiting");
sw.Flush();
pipeServer.WaitForPipeDrain();
test = sr.ReadLine();
if (!string.IsNullOrEmpty(test))
try
{
System.Windows.Application.Current.Dispatcher.Invoke(new Action(() => MbxTw.Show(Convert.ToInt32(test.Split(',')[1]), test.Split(',')[0], "method()", "Warning!! - " + "content")), System.Windows.Threading.DispatcherPriority.Normal);
}
catch (Exception e)
{
}
}
catch (Exception ex) {
throw ex; }
finally
{
pipeServer.WaitForPipeDrain();
if (pipeServer.IsConnected) { pipeServer.Disconnect(); }
}
} while (true);
}
after a thorough research on inter process communication I have changed the approach from using Named pipes to Memory mapped files,
as it is all rounds winner, no need to recreate it and faster
I present the ultimate partitioned-global-app-inter-process communication
any thoughts on the code will be greatly appreciated!
public class MMFinterComT
{
public EventWaitHandle flagCaller1, flagCaller2, flagReciver1, flagReciver2;
private System.IO.MemoryMappedFiles.MemoryMappedFile mmf;
private System.IO.MemoryMappedFiles.MemoryMappedViewAccessor accessor;
public virtual string DepositChlName { get; set; }
public virtual string DepositThrdName { get; set; }
public virtual int DepositSize { get; set; }
private System.Threading.Thread writerThread;
private bool writerThreadRunning;
public int ReadPosition { get; set; }
public List<string> statusSet;
private int writePosition;
public int WritePosition
{
get { return writePosition; }
set
{
if (value != writePosition)
{
this.writePosition = value;
this.accessor.Write(WritePosition + READ_CONFIRM_OFFSET, true);
}
}
}
private List<byte[]> dataToSend;
private const int DATA_AVAILABLE_OFFSET = 0;
private const int READ_CONFIRM_OFFSET = DATA_AVAILABLE_OFFSET + 1;
private const int DATA_LENGTH_OFFSET = READ_CONFIRM_OFFSET + 1;
private const int DATA_OFFSET = DATA_LENGTH_OFFSET + 10;
public IpcMMFinterComSF.MMFinterComTStatus IntercomStatus;
public MMFinterComT(string ctrIpcChannelNameStr, string ctrIpcThreadName, int ctrMMFSize)
{
this.DepositChlName = ctrIpcChannelNameStr;
this.Deposit Size = ctrMMFSize;
this.DepositThrdName = ctrIpcThreadName;
mmf = MemoryMappedFile.CreateOrOpen(DepositChlName, DepositSize);
accessor = mmf.CreateViewAccessor(0, DepositSize, System.IO.MemoryMappedFiles.MemoryMappedFileAccess.ReadWrite);//if (started)
//smLock = new System.Threading.Mutex(true, IpcMutxName, out locked);
ReadPosition = -1;
writePosition = -1;
this.dataToSend = new List<byte[]>();
this.statusSet = new List<string>();
}
public bool reading;
public byte[] ReadData;
public void StartReader()
{
if (this.IntercomStatus != IpcMMFinterComSF.MMFinterComTStatus._Null || ReadPosition < 0 || writePosition < 0)
return;
this.IntercomStatus = IpcMMFinterComSF.MMFinterComTStatus.PreparingReader;
System.Threading.Thread t = new System.Threading.Thread(ReaderThread);
t.IsBackground = true;
t.Start();
}
private void ReaderThread(object stateInfo)
{
// Checks if there is something to read.
this.IntercomStatus = IpcMMFinterComSF.MMFinterComTStatus.TryingToRead;
this.reading = accessor.ReadBoolean(ReadPosition + DATA_AVAILABLE_OFFSET);
if (this.reading)
{
this.IntercomStatus = IpcMMFinterComSF.MMFinterComTStatus.ReadingData;
// Checks how many bytes to read.
int availableBytes = accessor.ReadInt32(ReadPosition + DATA_LENGTH_OFFSET);
this.ReadData = new byte[availableBytes];
// Reads the byte array.
int read = accessor.ReadArray<byte>(ReadPosition + DATA_OFFSET, this.ReadData, 0, availableBytes);
// Sets the flag used to signal that there aren't available data anymore.
accessor.Write(ReadPosition + DATA_AVAILABLE_OFFSET, false);
// Sets the flag used to signal that data has been read.
accessor.Write(ReadPosition + READ_CONFIRM_OFFSET, true);
this.IntercomStatus = IpcMMFinterComSF.MMFinterComTStatus.FinishedReading;
}
else this.IntercomStatus = IpcMMFinterComSF.MMFinterComTStatus._Null;
}
public void Write(byte[] data)
{
if (ReadPosition < 0 || writePosition < 0)
throw new ArgumentException();
this.statusSet.Add("ReadWrite:-> " + ReadPosition + "-" + writePosition);
lock (this.dataToSend)
this.dataToSend.Add(data);
if (!writerThreadRunning)
{
writerThreadRunning = true;
writerThread = new System.Threading.Thread(WriterThread);
writerThread.IsBackground = true;
writerThread.Name = this.DepositThrdName;
writerThread.Start();
}
}
public void WriterThread(object stateInfo)
{
while (dataToSend.Count > 0 && !this.disposed)
{
byte[] data = null;
lock (dataToSend)
{
data = dataToSend[0];
dataToSend.RemoveAt(0);
}
while (!this.accessor.ReadBoolean(WritePosition + READ_CONFIRM_OFFSET))
System.Threading.Thread.Sleep(133);
// Sets length and write data.
this.accessor.Write(writePosition + DATA_LENGTH_OFFSET, data.Length);
this.accessor.WriteArray<byte>(writePosition + DATA_OFFSET, data, 0, data.Length);
// Resets the flag used to signal that data has been read.
this.accessor.Write(writePosition + READ_CONFIRM_OFFSET, false);
// Sets the flag used to signal that there are data avaibla.
this.accessor.Write(writePosition + DATA_AVAILABLE_OFFSET, true);
}
writerThreadRunning = false;
}
public virtual void Close()
{
if (accessor != null)
{
try
{
accessor.Dispose();
accessor = null;
}
catch { }
}
if (this.mmf != null)
{
try
{
mmf.Dispose();
mmf = null;
}
catch { }
}
disposed = true;
GC.SuppressFinalize(this);
}
private bool disposed;
}
and usage
instaciant once !
public static bool StartCurProjInterCom(IpcAccessorSetting curSrv, int DepoSize)
{
if(CurProjMMF ==null)
CurProjMMF = new MMFinterComT(curSrv.Channel.ToString(), curSrv.AccThreadName.ToString(), DepoSize);
CurProjMMF.flagCaller1 = new EventWaitHandle(false, EventResetMode.ManualReset, CurProjMMF.DepositThrdName);
CurProjMMF.flagCaller2 = new EventWaitHandle(false, EventResetMode.ManualReset, CurProjMMF.DepositThrdName);
CurProjMMF.flagReciver1 = new EventWaitHandle(false, EventResetMode.ManualReset, IpcAccessorThreadNameS.DebuggerThrd.ToString());
CurProjMMF.ReadPosition = curSrv.AccessorSectorsSets.DepoSects.Setter.Read;
CurProjMMF.WritePosition = curSrv.AccessorSectorsSets.DepoSects.Setter.Write;
Console.WriteLine("MMFInterComSetter.ReadPosition " + CurProjMMF.ReadPosition);
Console.WriteLine("MMFInterComSetter.WritePosition " + CurProjMMF.WritePosition);
CurProjMMF.StartReader();
return true;
}
use many
public static void StartADebugerInterComCall(IpcCarier SetterDataObj)
{
IpcAccessorSetting curSrv = new IpcAccessorSetting(IpcMMf.IPChannelS.Debugger, IpcAccessorThreadNameS.DebuggerThrdCurProj, 0, 5000);
StartCurProjInterCom(curSrv, 10000);
var dataW = SetterDataObj.IpcCarierToByteArray();//System.Text.Encoding.UTF8.GetBytes(msg);
CurProjMMF.Write(dataW);
CurProjMMF.flagReciver1.Set();
CurProjMMF.flagCaller1.WaitOne();
CurProjMMF.flagCaller1.Reset();
}
I am developing a payroll system in which the attendance should be recorded from finger print machine.I have installed the SDK software, but I don't know how to deploy this in my web application. Also how can we save the finger print in our database so that we could save the attendance details according to finger print
thanks in advance
Fareeda Hussain
We have a project like this one before. You need an sdk (software development kit) to go to your device. Add that to your project references so you can communicate with it. And I believe there is a sample code in the SDK site that you could find in the case of your finger print reader which you could modify.
Anyway here is our sample code for saving fingerprint directly in the database.
private void SaveButton_Click(object sender, EventArgs e)
{
MemoryStream fingerprintData = new MemoryStream();
Template.Serialize(fingerprintData);
fingerprintData.Position = 0;
BinaryReader br = new BinaryReader(fingerprintData);
Byte[] bytes = br.ReadBytes((Int32)fingerprintData.Length);
//Insert the file into database
SqlConnection cn = new SqlConnection("Data Source=10.115.5.3; Initial Catalog=EnrollmentSampledb;Integrated Security=SSPI;");
SqlCommand cmd = new SqlCommand("INSERT INTO tblUser VALUES(#ID_NUMBER, #FIRSTNAME, #LASTNAME, #FINGERPRINT, #DATE_ADDED, #DATE_MODIFIED)", cn);
cmd.Parameters.Add("ID_NUMBER", SqlDbType.NVarChar).Value = tboxIdNum.Text;
cmd.Parameters.Add("FIRSTNAME", SqlDbType.NVarChar).Value = tboxFname.Text;
cmd.Parameters.Add("LASTNAME", SqlDbType.NVarChar).Value = tboxLname.Text;
cmd.Parameters.Add("FINGERPRINT", SqlDbType.Image).Value = bytes;
cmd.Parameters.Add("DATE_ADDED", SqlDbType.DateTime).Value = DateTime.Now;
cmd.Parameters.Add("DATE_MODIFIED", SqlDbType.DateTime).Value = DateTime.Now;
cn.Open();
cmd.ExecuteNonQuery();
cn.Close();
tboxIdNum.Text = "";
tboxFname.Text = "";
tboxLname.Text = "";
}
see also my similar question here for saving fingerprint directly in the database.
region Funsional FingerPrint
protected void ReaderFPMachine()
{
_readerCollection = ReaderCollection.GetReaders();
foreach (Reader Reader in _readerCollection)
{
_fPMachineID = Reader.Description.SerialNumber;
break;
}
this.CheckFingerPrint();
}
protected void CheckFingerPrint()
{
try
{
_finger = null;
_reader = _readerCollection[0];
if (!OpenReader())
{
//this.Close();
}
if (!StartCaptureAsync(this.OnCaptured))
{
//this.Close();
}
}
catch (Exception ex)
{
}
}
private void OnCaptured(CaptureResult captureResult)
{
try
{
_finger = null;
// Check capture quality and throw an error if bad.
if (!CheckCaptureResult(captureResult)) return;
//SendMessage(Action.SendMessage, "A finger was captured.");
DataResult<Fmd> resultConversion = FeatureExtraction.CreateFmdFromFid(captureResult.Data, Constants.Formats.Fmd.ANSI);
if (resultConversion.ResultCode != Constants.ResultCode.DP_SUCCESS)
{
_reset = true;
throw new Exception(resultConversion.ResultCode.ToString());
}
_finger = resultConversion.Data;
_fingerPrintID = Fmd.SerializeXml(_finger);
//MsVisitorHd _msVisitorHd = this._vMSBL.GetSingleMsVisitorHdByFingerPrintID(_fingerXML);
//List<MsVisitorHd> _listMsVisitorHd = this._vMSBL.GetListMsVisitorHd();
bool _exist = false;
//foreach (var _item in _listMsVisitorHd)
//{
// Fmd _fmd = Fmd.DeserializeXml(_fingerPrintID);
// Fmd _fmd2 = Fmd.DeserializeXml(_item.FingerPrintID);
// CompareResult compareResult = Comparison.Compare(_fmd, 0, _fmd2, 0);
// if (compareResult.ResultCode != Constants.ResultCode.DP_SUCCESS)
// {
// _reset = true;
// throw new Exception(compareResult.ResultCode.ToString());
// }
// else
// {
// if (compareResult.Score < (PROBABILITY_ONE / 100000))
// {
// //_visitorExist = new MsVisitorHd();
// //_visitorExist = _item;
// _exist = true;
// break;
// }
// else
// {
// }
// }
//}
if (!CheckCaptureResult(captureResult)) return;
// Create bitmap
foreach (Fid.Fiv fiv in captureResult.Data.Views)
{
this.FingerPictureBox.BackgroundImage = CreateBitmap(fiv.RawImage, fiv.Width, fiv.Height);
}
if (_exist)
{
_fgMember = "Y";
//MessageBox.Show("Sidik jadi terdaftar sebagai " + _visitorExist.VisitorName);
}
else
{
_fgMember = "N";
}
//SendMessage(Action.SendMessage, secondFinger.Bytes.ToString() + "Comparison resulted in a dissimilarity score of " + compareResult.Score.ToString() + (compareResult.Score < (PROBABILITY_ONE / 100000) ? " (fingerprints matched)" : " (fingerprints did not match)"));
//SendMessage(Action.SendMessage, "Place a finger on the reader.");
// count = 0;
//}
}
catch (Exception ex)
{
// Send error message, then close form
//SendMessage(Action.SendMessage, "Error: " + ex.Message);
}
}
public bool OpenReader()
{
_reset = false;
Constants.ResultCode result = Constants.ResultCode.DP_DEVICE_FAILURE;
// Open reader
result = _reader.Open(Constants.CapturePriority.DP_PRIORITY_COOPERATIVE);
if (result != Constants.ResultCode.DP_SUCCESS)
{
MessageBox.Show("Error: " + result);
_reset = true;
return false;
}
return _reset;
}
public void GetStatus()
{
Constants.ResultCode result = _reader.GetStatus();
if ((result != Constants.ResultCode.DP_SUCCESS))
{
_reset = true;
throw new Exception("" + result);
}
if ((_reader.Status.Status == Constants.ReaderStatuses.DP_STATUS_BUSY))
{
Thread.Sleep(50);
}
else if ((_reader.Status.Status == Constants.ReaderStatuses.DP_STATUS_NEED_CALIBRATION))
{
_reader.Calibrate();
}
else if ((_reader.Status.Status != Constants.ReaderStatuses.DP_STATUS_READY))
{
throw new Exception("Reader Status - " + _reader.Status.Status);
}
}
public bool CheckCaptureResult(CaptureResult captureResult)
{
if (captureResult.Data == null)
{
if (captureResult.ResultCode != Constants.ResultCode.DP_SUCCESS)
{
_reset = true;
throw new Exception(captureResult.ResultCode.ToString());
}
// Send message if quality shows fake finger
if ((captureResult.Quality != Constants.CaptureQuality.DP_QUALITY_CANCELED))
{
throw new Exception("Quality - " + captureResult.Quality);
}
return false;
}
return true;
}
public bool CaptureFingerAsync()
{
try
{
GetStatus();
Constants.ResultCode captureResult = _reader.CaptureAsync(Constants.Formats.Fid.ANSI, Constants.CaptureProcessing.DP_IMG_PROC_DEFAULT, _reader.Capabilities.Resolutions[0]);
if (captureResult != Constants.ResultCode.DP_SUCCESS)
{
_reset = true;
throw new Exception("" + captureResult);
}
return true;
}
catch (Exception ex)
{
MessageBox.Show("Error: " + ex.Message);
return false;
}
}
public Bitmap CreateBitmap(byte[] bytes, int width, int height)
{
byte[] rgbBytes = new byte[bytes.Length * 3];
for (int i = 0; i <= bytes.Length - 1; i++)
{
rgbBytes[(i * 3)] = bytes[i];
rgbBytes[(i * 3) + 1] = bytes[i];
rgbBytes[(i * 3) + 2] = bytes[i];
}
Bitmap bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb);
BitmapData data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
for (int i = 0; i <= bmp.Height - 1; i++)
{
IntPtr p = new IntPtr(data.Scan0.ToInt64() + data.Stride * i);
System.Runtime.InteropServices.Marshal.Copy(rgbBytes, i * bmp.Width * 3, p, bmp.Width * 3);
}
bmp.UnlockBits(data);
return bmp;
}
public bool StartCaptureAsync(Reader.CaptureCallback OnCaptured)
{
// Activate capture handler
_reader.On_Captured += new Reader.CaptureCallback(OnCaptured);
// Call capture
if (!CaptureFingerAsync())
{
return false;
}
return true;
}
#endregion
I am running a loop in C# that reads a file and make updates to the MySQL database with MySQL ODBC 5.1 driver in a Windows 8 64-bit environment.
The operations is simple
Count +1
See if file exists
Load XML file(XDocument)
Fetch data from XDocument
Open ODBCConnection
Run a couple of Stored Procedures against the MySQL database to store data
Close ODBCConnection
The problem is that after a while it will hang on for example a OdbcCommand.ExecuteNonQuery. It is not always the same SP that it will hang on?
This is a real problem, I need to loop 60 000 files but it only last around 1000 at a time.
Edit 1:
The problem seemse to accure here hever time :
public bool addPublisherToGame(int inPublisherId, int inGameId)
{
string sqlStr;
OdbcCommand commandObj;
try
{
sqlStr = "INSERT INTO games_publisher_binder (gameId, publisherId) VALUE(?,?)";
commandObj = new OdbcCommand(sqlStr, mainConnection);
commandObj.Parameters.Add("#gameId", OdbcType.Int).Value = inGameId;
commandObj.Parameters.Add("#publisherId", OdbcType.Int).Value = inPublisherId;
if (Convert.ToInt32(executeNonQuery(commandObj)) > 0)
return true;
else
return false;
}
catch (Exception ex)
{
throw (loggErrorMessage(this.ToString(), "addPublisherToGame", ex, -1, "", ""));
}
finally
{
}
}
protected object executeNonQuery(OdbcCommand inCommandObj)
{
try
{
//FileStream file = new FileStream("d:\\test.txt", FileMode.Append, FileAccess.Write);
//System.IO.StreamWriter stream = new System.IO.StreamWriter(file);
//stream.WriteLine(DateTime.Now.ToString() + " - " + inCommandObj.CommandText);
//stream.Close();
//file.Close();
//mainConnection.Open();
return inCommandObj.ExecuteNonQuery();
}
catch (Exception ex)
{
throw (ex);
}
}
I can see that the in parameters is correct
The open and close of the connection is done in a top method for ever loop (with finally).
Edit 2:
This is the method that will extract the information and save to database :
public Boolean addBoardgameToDatabase(XElement boardgame, GameFactory gameFactory)
{
int incomingGameId = -1;
XElement tmpElement;
string primaryName = string.Empty;
List<string> names = new List<string>();
GameStorage externalGameStorage;
int retry = 3;
try
{
if (boardgame.FirstAttribute != null &&
boardgame.FirstAttribute.Value != null)
{
while (retry > -1)
{
try
{
incomingGameId = int.Parse(boardgame.FirstAttribute.Value);
#region Find primary name
tmpElement = boardgame.Elements("name").Where(c => c.Attribute("primary") != null).FirstOrDefault(a => a.Attribute("primary").Value.Equals("true"));
if (tmpElement != null)
primaryName = tmpElement.Value;
else
return false;
#endregion
externalGameStorage = new GameStorage(incomingGameId,
primaryName,
string.Empty,
getDateTime("1/1/" + boardgame.Element("yearpublished").Value),
getInteger(boardgame.Element("minplayers").Value),
getInteger(boardgame.Element("maxplayers").Value),
boardgame.Element("playingtime").Value,
0, 0, false);
gameFactory.updateGame(externalGameStorage);
gameFactory.updateGameGrade(incomingGameId);
gameFactory.removeDesignersFromGame(externalGameStorage.id);
foreach (XElement designer in boardgame.Elements("boardgamedesigner"))
{
gameFactory.updateDesigner(int.Parse(designer.FirstAttribute.Value), designer.Value);
gameFactory.addDesignerToGame(int.Parse(designer.FirstAttribute.Value), externalGameStorage.id);
}
gameFactory.removePublishersFromGame(externalGameStorage.id);
foreach (XElement publisher in boardgame.Elements("boardgamepublisher"))
{
gameFactory.updatePublisher(int.Parse(publisher.FirstAttribute.Value), publisher.Value, string.Empty);
gameFactory.addPublisherToGame(int.Parse(publisher.FirstAttribute.Value), externalGameStorage.id);
}
foreach (XElement element in boardgame.Elements("name").Where(c => c.Attribute("primary") == null))
names.Add(element.Value);
gameFactory.removeGameNames(incomingGameId);
foreach (string name in names)
if (name != null && name.Length > 0)
gameFactory.addGameName(incomingGameId, name);
return true;
}
catch (Exception)
{
retry--;
if (retry < 0)
return false;
}
}
}
return false;
}
catch (Exception ex)
{
throw (new Exception(this.ToString() + ".addBoardgameToDatabase : " + ex.Message, ex));
}
}
And then we got one step higher, the method that will trigger addBoardgameToDatabase :
private void StartThreadToHandleXmlFile(int gameId)
{
FileInfo fileInfo;
XDocument xmlDoc;
Boolean gameAdded = false;
GameFactory gameFactory = new GameFactory();
try
{
fileInfo = new FileInfo(_directory + "\\" + gameId.ToString() + ".xml");
if (fileInfo.Exists)
{
xmlDoc = XDocument.Load(fileInfo.FullName);
if (addBoardgameToDatabase(xmlDoc.Element("boardgames").Element("boardgame"), gameFactory))
{
gameAdded = true;
fileInfo.Delete();
}
else
return;
}
if (!gameAdded)
{
gameFactory.InactivateGame(gameId);
fileInfo.Delete();
}
}
catch (Exception)
{ throw; }
finally
{
if(gameFactory != null)
gameFactory.CloseConnection();
}
}
And then finally the top level :
public void UpdateGames(string directory)
{
DirectoryInfo dirInfo;
FileInfo fileInfo;
Thread thread;
int gameIdToStartOn = 1;
dirInfo = new DirectoryInfo(directory);
if(dirInfo.Exists)
{
_directory = directory;
fileInfo = dirInfo.GetFiles("*.xml").OrderBy(c=> int.Parse(c.Name.Replace(".xml",""))).FirstOrDefault();
gameIdToStartOn = int.Parse(fileInfo.Name.Replace(".xml", ""));
for (int gameId = gameIdToStartOn; gameId < 500000; gameId++)
{
try
{ StartThreadToHandleXmlFile(gameId); }
catch(Exception){}
}
}
}
Use SQL connection pooling by adding "Pooling=true" to your connectionstring.
Make sure you properly close the connection AND the file.
You can create one large query and execute it only once, I think it is a lot faster then 60.000 loose queries!
Can you show a bit of your code?
I am sharing a static array between a number of System.Threading.Timer simultaneously. This array is accessed only by the first timer thread & second timer will not accessed this array. An exception is displayed: "error can not evaluate expression a native frame is on top of the call stack in c#"
please reply
project code:
public partial class OPC_server : DevExpress.XtraEditors.XtraForm
{
private System.Threading.Timer timer1;
private System.Threading.Timer timer2;
parameter param = new parameter();//another class
private static readonly object myLockHolder = new object();
private static readonly object myLockHolder1 = new object();
public static OpcServer[] _opcServer;
private void OPC_server_Load(object sender, EventArgs e)
{
getconnectedOPC();
}
public void getconnectedOPC()
{
ds = opcconn.GetOPCServerInfo();
int i=0;
DataTable dtOPC=new DataTable();
if (ds.Tables[0].Rows.Count != 0 || ds.Tables[0] != null)
{
dtOPC = ds.Tables[0].Copy();
_opcServer = new OpcServer[dtOPC.Rows.Count];
TimeSpan delayTime = new TimeSpan(0, 0, 1);
TimeSpan intervalTime = new TimeSpan(0, 0, 0, 0, 450);
foreach (DataRow row in dtOPC.Rows)
{
if (i <= dtOPC.Rows.Count)
{
//connetion(row);
getconnect(i, row, dtOPC.Rows.Count);
i++;
}
}
connetion(dtOPC.Rows.Count);
}
}
//connecting the server
public void getconnect(int conn, DataRow r,int rows)
{
DataSet ds2=new DataSet();
DataTable dt2 = new DataTable();
try
{
string machinename = Convert.ToString(r["OPCIPAddress"]);
string servername = Convert.ToString(r["OPCName"]);
_opcServer[conn] = new OpcServer();
int i = _opcServer[conn].Connect(machinename, servername);
if (i == 0)
{
opcconn.update("true", servername);
writelog(servername, "connected");
}
else
{
opcconn.update("false", servername);
writelog(servername, "disconnected");
}
}
catch (OPCException e)
{
servername = Convert.ToString(r["OPCName"]);
opcconn.update("false", servername);
writelog(servername, e.Message.ToString());
}
catch (ApplicationException e)
{
servername = Convert.ToString(r["OPCName"]);
opcconn.update("false", servername);
writelog(servername, "No instance server");
}
}
public void connetion(object state)
{
int k ,i,q=0;
k = (System.Int32)state;
DataSet dsgroup=new DataSet();
while(j < k)
{
try
{
bool val;
HRESULTS re;
SrvStatus status;
DateTime dt;
i = _opcServer[j].GetStatus(out status);
if (HRESULTS.Failed(i))
{
try
{
opcconn.update("false", _opcServer[j].ServerName.ToString());
string IP = opcconn.search(_opcServer[j].ServerName.ToString());
_opcServer[j].Connect(IP, _opcServer[j].ServerName.ToString());
opcconn.update("true", _opcServer[j].ServerName.ToString());
j++;
}
catch
{
opcconn.update("false", _opcServer[j].ServerName.ToString());
j++;
}
}
else
{
val = HRESULTS.Succeeded(i);
dsgroup = grpclass.getgroupinfo(j + 1);
if (dsgroup.Tables[0].Rows.Count != 0)
{
grpdt = new DataTable();
grpdt = dsgroup.Tables[0].Copy();
foreach (DataRow Row in grpdt.Rows)
{
if (groupcnt <= 128)
{
if (cntgroup < grpdt.Rows.Count)
{
grp = _opcServer[j].AddGroup((Convert.ToString(Row["GroupName"])), (Convert.ToBoolean(Row["setactive"])), (Convert.ToInt32(Row["refreshRate"])), 1);
ds1 = param.getparameter1(Convert.ToInt32(Row["groupID"]));
if (ds1.Tables[0].Rows.Count != 0)
{
dt1 = ds1.Tables[0].Copy();
int tq = 0;
item1 = new OPCItemDef[dt1.Rows.Count];
int clienthandle = 1;
foreach (DataRow r in dt1.Rows)
{
if (tq < item1.Length)
{
item1[tq] = new OPCItemDef(Convert.ToString(r["param_ID"]), Convert.ToBoolean(r["active"]), clienthandle, VarEnum.VT_EMPTY);
++clienthandle;
tq++;
}
}
int y = grp.AddItems(item1, out addRslt);
// thread started like each group assign one thread
OPCthread(Row, groupcnt);
groupcnt++;
cntgroup++;
}
}
}
}
}
cntgroup = 0;
j++;
}
}
catch (OPCException)
{
string servername = opcconn.getserver(j + 1);
string IPadd = opcconn.search(servername);
_opcServer[j].Connect(IPadd, servername);
}
catch (IndexOutOfRangeException)
{
j = 0;
}
catch (InvalidCastException e)
{
try
{
// writelog1(_opcServer[j].ServerName.ToString(), "disconnected");
opcconn.update("false", _opcServer[j].ServerName.ToString());
string IP = opcconn.search(_opcServer[j].ServerName.ToString());
_opcServer[j].Connect(IP, _opcServer[j].ServerName.ToString());
opcconn.update("true", _opcServer[j].ServerName.ToString());
j++;
}
catch
{
// writelog1(_opcServer[j].ServerName.ToString(), "connection failed");
opcconn.update("true", _opcServer[j].ServerName.ToString());
j++;
}
}
catch (ArgumentOutOfRangeException)
{
j = 0;
}
catch (NullReferenceException)
{
try
{
// writelog1("server'" + j + "' ", "no server instance");
OPC1 = opcconn.getserver(j + 1);
string IPA = opcconn.search(OPC1);
_opcServer[j].Connect(IPA, OPC1);
opcconn.update("true", OPC1);
writelog(OPC1, "connected");
j++;
}
catch (OPCException e)
{
opcconn.update("false", OPC1);
writelog(OPC1, e.Message.ToString());
j++;
}
catch (ApplicationException e)
{
opcconn.update("false", OPC1);
writelog(OPC1, "No instance server");
j++;
}
}
}
}
public void OPCthread(DataRow r2,int timerinfo)
{
if (timerinfo == 0)
{
int rer = Convert.ToInt32(r2["refreshRate"]);//at least 1 second
TimeSpan dueTime = new TimeSpan(0, 0,0,0,rer);
TimeSpan interval = new TimeSpan(0, 0, 0 ,0 ,rer);
timer1 = new System.Threading.Timer(register, r2, dueTime,interval);
}
else if (timerinfo == 1)
{
TimeSpan dueTime;
TimeSpan interval;
int rer1 = Convert.ToInt32(r2["refreshRate"]);
dueTime = new TimeSpan(0, 0, 0, 0, rer1);
interval = new TimeSpan(0, 0, 0, 0, rer1);
timer2 = new System.Threading.Timer(register1, r2, dueTime, interval);
}
}
public void register(object row1)
{
try
{
lock (myLockHolder)
{
int cnt = 0, cnt1 = 0;
ItemValue[] rVals;
OPCItemDef[] item;
OpcServer srv = new OpcServer();
string[] array;
//SrvStatus status1;
DataSet paramds = new DataSet();
DataTable paramdt = new DataTable();
DataRow dt = (System.Data.DataRow)row1;
int serverID = Convert.ToInt32(dt["OPCServerID"]);
paramds = param.getparameter(Convert.ToInt32(dt["groupID"]));
if (Convert.ToBoolean(dt["setactive"]) == true)
{
if (paramds != null && paramds.Tables[0].Rows.Count != 0)
{
paramdt = paramds.Tables[0].Copy();
int tq = 0;
item = new OPCItemDef[paramdt.Rows.Count];
int clienthandle = 1;
foreach (DataRow r in paramdt.Rows)
{
if (tq < item.Length)
{
item[tq] = new OPCItemDef(Convert.ToString(r["param_ID"]), Convert.ToBoolean(r["active"]), clienthandle, VarEnum.VT_EMPTY);
++clienthandle;
tq++;
}
}
array = new string[item.Length];
cnt1 = 0;
while (cnt1 < array.Length)
{
array[cnt1] = item[cnt1].ItemID;
cnt1++;
}
rVals = _opcServer[serverID - 1].Read(array, Convert.ToInt32(dt["refreshRate"]));
//this line i got the exception when i checking the value of the _opcserver varible in locals the it will be display as "error can not evaluate expression a native frame is on top of the call stack in c#" & thread will stop the execution.
param.update(rVals, Convert.ToInt32(dt["groupID"]));
}
}
}
}
catch (ThreadAbortException) { }
finally { }
}
public void register1(object row2)
{
try
{
lock (myLockHolder1)
{
int cnt = 0, cnt11 = 0;
ItemValue[] rVals1;
OPCItemDef[] item1;
OpcServer srv1 = new OpcServer();
string[] array1;
DataSet paramds1 = new DataSet();
DataTable paramdt1 = new DataTable();
DataRow dt1 = (System.Data.DataRow)row2;
int serverID1 = Convert.ToInt32(dt1["OPCServerID"]);
// Boolean gstatus = grpclass.getstatus(Convert.ToInt32(dt["groupID"]));
paramds1 = param.getparameter2(Convert.ToInt32(dt1["groupID"]));
if (Convert.ToBoolean(dt1["setactive"]) == true)
{
if (paramds1 != null)
{
paramdt1 = paramds1.Tables[0].Copy();
int tq1 = 0;
item1 = new OPCItemDef[paramdt1.Rows.Count];
int clienthandle1 = 1;
foreach (DataRow r in paramdt1.Rows)
{
if (tq1 < item1.Length)
{
item1[tq1] = new OPCItemDef(Convert.ToString(r["param_ID"]), Convert.ToBoolean(r["active"]), clienthandle1, VarEnum.VT_EMPTY);
clienthandle1++;
tq1++;
}
}
array1 = new string[item1.Length];
cnt11 = 0;
while (cnt11 < array1.Length)
{
array1[cnt11] = item1[cnt11].ItemID;
cnt11++;
}
rvals = _opcServer[serverID1 - 1].Read(array1, Convert.ToInt32(dt1["refreshRate"]));//this line i got the exception when i checking the value of the _opcserver varible in locals the it will be display as "error can not evaluate expression a native frame is on top of the call stack in c#" & thread will stop the execution.
param.update1(rVals1, Convert.ToInt32(dt1["groupID"]));
}
}
}
}
catch { }
finally { }
}
The error you are seeing is not an Exception. The message you see is just letting you know that a native frame is on the top of the stack instead of a managed frame.
It's possible that the error you're seeing has nothing to do with the array - but it's difficult to tell without seeing some of your code.
There are two very common problems involved with multi-threaded programs. If I had to take a guess, you're getting an InvalidOperationException either because the "Object is currently in use" or because "Cross-thread operation not valid".
If the first is the case, you need to use something like:
lock (myObject)
{
// Alter myObject
}
see Locks.
And if the second is the case, you need to use something like:
Invoke(new MethodInvoker(delegate()
{
// Alter stuff in Forms/Controls
}));
see Invoke.
It would really help if you could post the exact Exception you're getting and the code which produces it.
Edit: You have posted a mountain of code to look through. It is very unhelpful.
You say the line causing it is
rvals = _opcServer[serverID1 - 1].Read(array1, Convert.ToInt32(dt1["refreshRate"]));
but nowhere in your code can I see you have declared the variable _opcServer.
As I have already told you, the native frame message isn't an Exception and doesn't mean that there is anything wrong with your program! - it's simply the debugger telling you that it can't give you the values of the managed variables.
Please put this code around the line to identify which type of Exception you are getting, and tell me what the Exception is.
try
{
rvals = _opcServer[serverID1 - 1].Read(array1, Convert.ToInt32(dt1["refreshRate"]));
}
catch (System.Exception ex)
{
System.Windows.Forms.MessageBox.Show("Exception: " + ex.GetType().ToString() +
"\r\nMessage: " + ex.Message);
}