Inter-process communication sample-server & client C# - c#

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();
}

Related

System.OutOfMemoryException in C# when Generating huge amount of byte[] objects

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;
}
}

How to create TCP message framing for the stream

Here is how my Client connects to the server:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.Net.Sockets;
using System.IO;
using System;
using System.Text.RegularExpressions;
using UnityEngine.SceneManagement;
using Newtonsoft.Json;
using System.Linq;
public class ClientWorldServer : MonoBehaviour {
public bool socketReady;
public static TcpClient socket;
public static NetworkStream stream;
public static StreamWriter writer;
public static StreamReader reader;
public void ConnectToWorldServer()
{
if (socketReady)
{
return;
}
//Default host and port values;
string host = "127.0.0.1";
int port = 8080;
try
{
socket = new TcpClient(host, port);
stream = socket.GetStream();
writer = new StreamWriter(stream);
reader = new StreamReader(stream);
socketReady = true;
}
catch (Exception e)
{
Debug.Log("Socket error : " + e.Message);
}
}
}
Here is how i send data to the server using my Send function:
public void Send(string header, Dictionary<string, string> data)
{
if (stream.CanRead)
{
socketReady = true;
}
if (!socketReady)
{
return;
}
JsonData SendData = new JsonData();
SendData.header = "1x" + header;
foreach (var item in data)
{
SendData.data.Add(item.Key.ToString(), item.Value.ToString());
}
SendData.connectionId = connectionId;
string json = JsonConvert.SerializeObject(SendData);
var howManyBytes = json.Length * sizeof(Char);
writer.WriteLine(json);
writer.Flush();
Debug.Log("Client World:" + json);
}
As you can see i'm sending the data to the Stream like a string not like a byte array. As far as i know i should send the data as byte array prepending the size of the message and following the message. On the server side i have no clue how i can read that data.
Here is how i read it now(it works for now, but it will not work if i try to send more messages at once):
class WorldServer
{
public List<ServerClient> clients = new List<ServerClient>();
public List<ServerClient> disconnectList;
public List<CharactersOnline> charactersOnline = new List<CharactersOnline>();
public int port = 8080;
private TcpListener server;
private bool serverStarted;
private int connectionIncrementor;
private string mysqlConnectionString = #"server=xxx;userid=xxx;password=xxx;database=xx";
private MySqlConnection mysqlConn = null;
private MySqlDataReader mysqlReader;
static void Main(string[] args)
{
WorldServer serverInstance = new WorldServer();
Console.WriteLine("Starting World Server...");
try
{
serverInstance.mysqlConn = new MySqlConnection(serverInstance.mysqlConnectionString);
serverInstance.mysqlConn.Open();
Console.WriteLine("Connected to MySQL version: " + serverInstance.mysqlConn.ServerVersion + "\n");
}
catch (Exception e)
{
Console.WriteLine("MySQL Error: " + e.ToString());
}
finally
{
if (serverInstance.mysqlConn != null)
{
serverInstance.mysqlConn.Close();
}
}
serverInstance.clients = new List<ServerClient>();
serverInstance.disconnectList = new List<ServerClient>();
try
{
serverInstance.server = new TcpListener(IPAddress.Any, serverInstance.port);
serverInstance.server.Start();
serverInstance.StartListening();
serverInstance.serverStarted = true;
Console.WriteLine("Server has been started on port: " + serverInstance.port);
}
catch (Exception e)
{
Console.WriteLine("Socket error: " + e.Message);
}
new Thread(() =>
{
Thread.CurrentThread.IsBackground = true;
/* run your code here */
while (true)
{
string input = Console.ReadLine();
string[] commands = input.Split(':');
if (commands[0] == "show online players")
{
Console.WriteLine("Showing connections\n");
foreach (CharactersOnline c in serverInstance.charactersOnline)
{
Console.WriteLine("Character name: " + c.characterName + "Character ID: " + c.characterId + "Connection id: " + c.connectionId + "\n");
}
}
continue;
}
}).Start();
while (true)
{
serverInstance.Update();
}
}
private void Update()
{
//Console.WriteLine("Call");
if (!serverStarted)
{
return;
}
foreach (ServerClient c in clients.ToList())
{
// Is the client still connected?
if (!IsConnected(c.tcp))
{
c.tcp.Close();
disconnectList.Add(c);
Console.WriteLine(c.connectionId + " has disconnected.");
CharacterLogout(c.connectionId);
continue;
//Console.WriteLine("Check for connection?\n");
}
else
{
// Check for message from Client.
NetworkStream s = c.tcp.GetStream();
if (s.DataAvailable)
{
StreamReader reader = new StreamReader(s, true);
string data = reader.ReadLine();
if (data != null)
{
OnIncomingData(c, data);
}
}
//continue;
}
}
for (int i = 0; i < disconnectList.Count - 1; i++)
{
clients.Remove(disconnectList[i]);
disconnectList.RemoveAt(i);
}
}
private void OnIncomingData(ServerClient c, string data)
{
Console.WriteLine(data);
dynamic json = JsonConvert.DeserializeObject(data);
string header = json.header;
//Console.WriteLine("Conn ID:" + json.connectionId);
string connId = json.connectionId;
int.TryParse(connId, out int connectionId);
string prefix = header.Substring(0, 2);
if (prefix != "1x")
{
Console.WriteLine("Unknown packet: " + data + "\n");
}
else
{
string HeaderPacket = header.Substring(2);
switch (HeaderPacket)
{
default:
Console.WriteLine("Unknown packet: " + data + "\n");
break;
case "004":
int accountId = json.data["accountId"];
SelectAccountCharacters(accountId, connectionId);
break;
case "005":
int characterId = json.data["characterId"];
getCharacterDetails(characterId, connectionId);
break;
case "006":
int charId = json.data["characterId"];
SendDataForSpawningOnlinePlayers(charId, connectionId);
break;
case "008":
Dictionary<string, string> dictObj = json.data.ToObject<Dictionary<string, string>>();
UpdateCharacterPosition(dictObj, connectionId);
break;
}
}
private bool IsConnected(TcpClient c)
{
try
{
if (c != null && c.Client != null && c.Client.Connected)
{
if (c.Client.Poll(0, SelectMode.SelectRead))
{
return !(c.Client.Receive(new byte[1], SocketFlags.Peek) == 0);
}
return true;
}
else
{
return false;
}
}
catch
{
return false;
}
}
private void StartListening()
{
server.BeginAcceptTcpClient(OnConnection, server);
}
private void OnConnection(IAsyncResult ar)
{
connectionIncrementor++;
TcpListener listener = (TcpListener)ar.AsyncState;
clients.Add(new ServerClient(listener.EndAcceptTcpClient(ar)));
clients[clients.Count - 1].connectionId = connectionIncrementor;
StartListening();
//Send a message to everyone, say someone has connected!
Dictionary<string, string> SendDataBroadcast = new Dictionary<string, string>();
SendDataBroadcast.Add("connectionId", clients[clients.Count - 1].connectionId.ToString());
Broadcast("001", SendDataBroadcast, clients, clients[clients.Count - 1].connectionId);
Console.WriteLine(clients[clients.Count - 1].connectionId + " has connected.");
}
And this is how the server send back data to the client:
private void Send(string header, Dictionary<string, string> data, int cnnId)
{
foreach (ServerClient c in clients.ToList())
{
if (c.connectionId == cnnId)
{
try
{
//Console.WriteLine("Sending...");
StreamWriter writer = new StreamWriter(c.tcp.GetStream());
if (header == null)
{
header = "000";
}
JsonData SendData = new JsonData();
SendData.header = "0x" + header;
foreach (var item in data)
{
SendData.data.Add(item.Key.ToString(), item.Value.ToString());
}
SendData.connectionId = cnnId;
string JSonData = JsonConvert.SerializeObject(SendData);
writer.WriteLine(JSonData);
writer.Flush();
//Console.WriteLine("Trying to send data to connection id: " + cnnId + " data:" + sendData);
}
catch (Exception e)
{
Console.WriteLine("Write error : " + e.Message + " to client " + c.connectionId);
}
}
}
}
Here is my ServerClient class:
public class ServerClient
{
public TcpClient tcp;
public int accountId;
public int connectionId;
public ServerClient(TcpClient clientSocket)
{
tcp = clientSocket;
}
}
Can you please show me how i should modify my Send function on the client to send the data as byte array so i can create "TCP Message Framing" and how should i change my the following part on the server:
foreach (ServerClient c in clients.ToList())
{
// Is the client still connected?
if (!IsConnected(c.tcp))
{
c.tcp.Close();
disconnectList.Add(c);
Console.WriteLine(c.connectionId + " has disconnected.");
CharacterLogout(c.connectionId);
continue;
//Console.WriteLine("Check for connection?\n");
}
else
{
// Check for message from Client.
NetworkStream s = c.tcp.GetStream();
if (s.DataAvailable)
{
StreamReader reader = new StreamReader(s, true);
string data = reader.ReadLine();
if (data != null)
{
OnIncomingData(c, data);
}
}
//continue;
}
}
which is responsible for receving data on the server ?
Is it possible to change only these parts from the Client and on the Server and make it continue to work but this time properly with TCP Message Framing ?
Of course the listener on the client and the Send function of the server i'll remake once i understand how this framing should look like.
Your frames are already defined by cr/lf - so that much already exists; what you need to do is to keep a back buffer per stream - something like a MemoryStream might be sufficient, depending on how big you need to scale; then essentially what you're looking to do is something like:
while (s.DataAvailable)
{
// try to read a chunk of data from the inbound stream
int bytesRead = s.Read(someBuffer, 0, someBuffer.Length);
if(bytesRead > 0) {
// append to our per-socket back-buffer
perSocketStream.Position = perSocketStream.Length;
perSocketStream.Write(someBuffer, 0, bytesRead);
int frameSize; // detect any complete frame(s)
while((frameSize = DetectFirstCRLF(perSocketStream)) >= 0) {
// decode it as text
var backBuffer = perSocketStream.GetBuffer();
string message = encoding.GetString(
backBuffer, 0, frameSize);
// remove the frame from the start by copying down and resizing
Buffer.BlockCopy(backBuffer, frameSize, backBuffer, 0,
(int)(backBuffer.Length - frameSize));
perSocketStream.SetLength(backBuffer.Length - frameSize);
// process it
ProcessMessage(message);
}
}
}

stm32f4 discovery sample of using USB to communicate with pc or read/write pendrive using net micro framework

I cannot find any sample of using USB port of STM32F4 Discovery board in .NET Micro Framework. I'm trying to learn how to use USB port to send or write data. Where can I find such examples?
I've tried to make sample application based on https://guruce.com/blogpost/communicating-with-your-microframework-application-over-usb but it doesn't work.
This is part of my code sample:
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using Microsoft.SPOT.Hardware.UsbClient;
using System;
using System.Text;
using System.Threading;
namespace MFConsoleApplication1
{
public class Program
{
private const int WRITE_EP = 1;
private const int READ_EP = 2;
private static bool ConfigureUSBController(UsbController usbController)
{
bool bRet = false;
// Create the device descriptor
Configuration.DeviceDescriptor device = new Configuration.DeviceDescriptor(0xDEAD, 0x0001, 0x0100);
device.bcdUSB = 0x110;
device.bDeviceClass = 0xFF; // Vendor defined class
device.bDeviceSubClass = 0xFF; // Vendor defined subclass
device.bDeviceProtocol = 0;
device.bMaxPacketSize0 = 8; // Maximum packet size of EP0
device.iManufacturer = 1; // String #1 is manufacturer name (see string descriptors below)
device.iProduct = 2; // String #2 is product name
device.iSerialNumber = 3; // String #3 is the serial number
// Create the endpoints
Configuration.Endpoint writeEP = new Configuration.Endpoint(WRITE_EP, Configuration.Endpoint.ATTRIB_Bulk | Configuration.Endpoint.ATTRIB_Write);
writeEP.wMaxPacketSize = 64;
writeEP.bInterval = 0;
Configuration.Endpoint readEP = new Configuration.Endpoint(READ_EP, Configuration.Endpoint.ATTRIB_Bulk | Configuration.Endpoint.ATTRIB_Read);
readEP.wMaxPacketSize = 64;
readEP.bInterval = 0;
Configuration.Endpoint[] usbEndpoints = new Configuration.Endpoint[] { writeEP, readEP };
// Set up the USB interface
Configuration.UsbInterface usbInterface = new Configuration.UsbInterface(0, usbEndpoints);
usbInterface.bInterfaceClass = 0xFF; // Vendor defined class
usbInterface.bInterfaceSubClass = 0xFF; // Vendor defined subclass
usbInterface.bInterfaceProtocol = 0;
// Create array of USB interfaces
Configuration.UsbInterface[] usbInterfaces = new Configuration.UsbInterface[] { usbInterface };
// Create configuration descriptor
Configuration.ConfigurationDescriptor config = new Configuration.ConfigurationDescriptor(500, usbInterfaces);
// Create the string descriptors
Configuration.StringDescriptor manufacturerName = new Configuration.StringDescriptor(1, Consts.MANUFACTURER);
Configuration.StringDescriptor productName = new Configuration.StringDescriptor(2, Consts.PRODUCT_NAME);
Configuration.StringDescriptor serialNumber = new Configuration.StringDescriptor(3, Consts.SERIAL_NO);
Configuration.StringDescriptor displayName = new Configuration.StringDescriptor(4, Consts.DISPLAYED_NAME);
Configuration.StringDescriptor friendlyName = new Configuration.StringDescriptor(5, Consts.FRENDLY_NAME);
// Create the final configuration
Configuration configuration = new Configuration();
configuration.descriptors = new Configuration.Descriptor[]
{
device,
config,
manufacturerName,
productName,
serialNumber,
displayName,
friendlyName
};
try
{
// Set the configuration
usbController.Configuration = configuration;
if (UsbController.ConfigError.ConfigOK != usbController.ConfigurationError)
throw new ArgumentException();
// If all ok, start the USB controller.
bRet = usbController.Start();
}
catch (ArgumentException)
{
Debug.Print(Consts.CONFIG_ERR + usbController.ConfigurationError.ToString());
}
return bRet;
}
private static string GetCommand(byte[] data)
{
return new string(Encoding.UTF8.GetChars(data));
}
private static byte[] GetDataToSend(Reading data, JsonSerializer serializer)
{
return Encoding.UTF8.GetBytes(serializer.Serialize(data));
}
private static void UsbMainLoop(UsbStream usbStream, AnalogInput supplyInput, AnalogInput dataInput, OutputPort recievingDataIndicator, OutputPort seindingDataIndicator, JsonSerializer dataSerializer)
{
byte[] readData = new byte[100];
for (;;)
{
recievingDataIndicator.Write(true);
int bytesRead = usbStream.Read(readData, 0, readData.Length);
recievingDataIndicator.Write(false);
if (bytesRead > 0)
{
string command = GetCommand(readData);
switch (command)
{
case "READ":
seindingDataIndicator.Write(true);
byte[] dataToSend = GetDataToSend(Reading.GetReading(supplyInput, dataInput), dataSerializer);
usbStream.Write(dataToSend, 0, dataToSend.Length);
seindingDataIndicator.Write(false);
break;
}
}
}
}
private static UsbController CheckSupportAndAccessibility(UsbController[] usbControllers, out string message)
{
UsbController usbController = null;
if (0 == usbControllers.Length)
{
message = Consts.USB_NOT_SUPPORTED;
}
else
{
bool foundedFreeUsb = false;
foreach (UsbController controller in usbControllers)
{
if (UsbController.PortState.Stopped == controller.Status)
{
usbController = controller;
foundedFreeUsb = true;
break;
}
}
if (foundedFreeUsb)
{
message = string.Empty;
}
else
{
message = Consts.NO_FREE_USB;
}
}
return usbController;
}
private static void OtherMainProgramLoop()
{
AnalogInput temperature0 = new AnalogInput(Cpu.AnalogChannel.ANALOG_0);
AnalogInput supply0 = new AnalogInput(Cpu.AnalogChannel.ANALOG_1);
double t0, r0, z0;
while (true)
{
z0 = supply0.Read() * 3;
r0 = Reading.GetRt(z0, temperature0.Read() * z0);
t0 = Reading.GetTemp(r0);
Debug.Print("Supply:" + z0.ToString() + "[V]");
Debug.Print("Rt:" + r0.ToString() + "[Ohm]");
Debug.Print("Temperature:" + t0.ToString() + "[^C]");
Thread.Sleep(1000);
}
}
public static void Main()
{
UsbController[] controllers = UsbController.GetControllers();
string msg;
UsbController usbController = CheckSupportAndAccessibility(controllers, out msg);
if (null == usbController)
{
Debug.Print(msg);
OtherMainProgramLoop();
//return;
}
else
{
UsbStream usbStream = null;
try
{
if (ConfigureUSBController(usbController))
usbStream = usbController.CreateUsbStream(WRITE_EP, READ_EP);
else
throw new Exception();
}
catch (Exception)
{
Debug.Print(Consts.USB_CREATE_STREAM_ERR + usbController.ConfigurationError.ToString());
OtherMainProgramLoop();
//return;
}
AnalogInput temperatureSource = new AnalogInput(Cpu.AnalogChannel.ANALOG_0);
AnalogInput supplySource = new AnalogInput(Cpu.AnalogChannel.ANALOG_1);
OutputPort ledGreen = new OutputPort((Cpu.Pin)60, false);
OutputPort ledYellow = new OutputPort((Cpu.Pin)61, false);
UsbMainLoop(usbStream, supplySource, temperatureSource, ledYellow, ledGreen, new JsonSerializer());
usbStream.Close();
}
}
}
}
Thanks for any help.

The code is giving error at MultiSheetsPdf

This is my code which create PDF of a dwg file but it gives me error near MultiSheetPdf. Please give me the solution for same.
I thought that linking is the problem but I am not able to identify please suggest me the solution.
namespace Plottings
{
public class MultiSheetsPdf
{
private string dwgFile, pdfFile, dsdFile, outputDir;
private int sheetNum;
private IEnumerable<Layout> layouts;
private const string LOG = "publish.log";
public MultiSheetsPdfPlot(string pdfFile, IEnumerable<Layout> layouts)
{
Database db = HostApplicationServices.WorkingDatabase;
this.dwgFile = db.Filename;
this.pdfFile = pdfFile;
this.outputDir = Path.GetDirectoryName(this.pdfFile);
this.dsdFile = Path.ChangeExtension(this.pdfFile, "dsd");
this.layouts = layouts;
}
public void Publish()
{
if (TryCreateDSD())
{
Publisher publisher = AcAp.Publisher;
PlotProgressDialog plotDlg = new PlotProgressDialog(false, this.sheetNum, true);
publisher.PublishDsd(this.dsdFile, plotDlg);
plotDlg.Destroy();
File.Delete(this.dsdFile);
}
}
private bool TryCreateDSD()
{
using (DsdData dsd = new DsdData())
using (DsdEntryCollection dsdEntries = CreateDsdEntryCollection(this.layouts))
{
if (dsdEntries == null || dsdEntries.Count <= 0) return false;
if (!Directory.Exists(this.outputDir))
Directory.CreateDirectory(this.outputDir);
this.sheetNum = dsdEntries.Count;
dsd.SetDsdEntryCollection(dsdEntries);
dsd.SetUnrecognizedData("PwdProtectPublishedDWF", "FALSE");
dsd.SetUnrecognizedData("PromptForPwd", "FALSE");
dsd.SheetType = SheetType.MultiDwf;
dsd.NoOfCopies = 1;
dsd.DestinationName = this.pdfFile;
dsd.IsHomogeneous = false;
dsd.LogFilePath = Path.Combine(this.outputDir, LOG);
PostProcessDSD(dsd);
return true;
}
}
private DsdEntryCollection CreateDsdEntryCollection(IEnumerable<Layout> layouts)
{
DsdEntryCollection entries = new DsdEntryCollection();
foreach (Layout layout in layouts)
{
DsdEntry dsdEntry = new DsdEntry();
dsdEntry.DwgName = this.dwgFile;
dsdEntry.Layout = layout.LayoutName;
dsdEntry.Title = Path.GetFileNameWithoutExtension(this.dwgFile) + "-" + layout.LayoutName;
dsdEntry.Nps = layout.TabOrder.ToString();
entries.Add(dsdEntry);
}
return entries;
}
private void PostProcessDSD(DsdData dsd)
{
string str, newStr;
string tmpFile = Path.Combine(this.outputDir, "temp.dsd");
dsd.WriteDsd(tmpFile);
using (StreamReader reader = new StreamReader(tmpFile, Encoding.Default))
using (StreamWriter writer = new StreamWriter(this.dsdFile, false, Encoding.Default))
{
while (!reader.EndOfStream)
{
str = reader.ReadLine();
if (str.Contains("Has3DDWF"))
{
newStr = "Has3DDWF=0";
}
else if (str.Contains("OriginalSheetPath"))
{
newStr = "OriginalSheetPath=" + this.dwgFile;
}
else if (str.Contains("Type"))
{
newStr = "Type=6";
}
else if (str.Contains("OUT"))
{
newStr = "OUT=" + this.outputDir;
}
else if (str.Contains("IncludeLayer"))
{
newStr = "IncludeLayer=TRUE";
}
else if (str.Contains("PromptForDwfName"))
{
newStr = "PromptForDwfName=FALSE";
}
else if (str.Contains("LogFilePath"))
{
newStr = "LogFilePath=" + Path.Combine(this.outputDir, LOG);
}
else
{
newStr = str;
}
writer.WriteLine(newStr);
}
}
File.Delete(tmpFile);
}
[CommandMethod("PlotPdf")]
public void PlotPdf()
{
Database db = HostApplicationServices.WorkingDatabase;
short bgp = (short)Application.GetSystemVariable("BACKGROUNDPLOT");
try
{
Application.SetSystemVariable("BACKGROUNDPLOT", 0);
using (Transaction tr = db.TransactionManager.StartTransaction())
{
List<Layout> layouts = new List<Layout>();
DBDictionary layoutDict =
(DBDictionary)db.LayoutDictionaryId.GetObject(OpenMode.ForRead);
foreach (DBDictionaryEntry entry in layoutDict)
{
if (entry.Key != "Model")
{
layouts.Add((Layout)tr.GetObject(entry.Value, OpenMode.ForRead));
}
}
layouts.Sort((l1, l2) => l1.TabOrder.CompareTo(l2.TabOrder));
string filename = Path.ChangeExtension(db.Filename, "pdf");
MultiSheetsPdf plotter = new MultiSheetsPdf(filename, layouts);
plotter.Publish();
tr.Commit();
}
}
catch (System.Exception e)
{
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
ed.WriteMessage("\nError: {0}\n{1}", e.Message, e.StackTrace);
}
finally
{
Application.SetSystemVariable("BACKGROUNDPLOT", bgp);
}
}
}
}
Here you go: (Try to note and understand the difference between your version and this version)
namespace Plottings
{
public class MultiSheetsPdf
{
private string dwgFile, pdfFile, dsdFile, outputDir;
private int sheetNum;
private IEnumerable<Layout> layouts;
private const string LOG = "publish.log";
public MultiSheetsPdf(){}
public MultiSheetsPdf(string pdfFile, IEnumerable<Layout> layouts)
{
Database db = HostApplicationServices.WorkingDatabase;
this.dwgFile = db.Filename;
this.pdfFile = pdfFile;
this.outputDir = Path.GetDirectoryName(this.pdfFile);
this.dsdFile = Path.ChangeExtension(this.pdfFile, "dsd");
this.layouts = layouts;
}
public void Publish()
{
if (TryCreateDSD())
{
Publisher publisher = AcAp.Publisher;
PlotProgressDialog plotDlg = new PlotProgressDialog(false, this.sheetNum, true);
publisher.PublishDsd(this.dsdFile, plotDlg);
plotDlg.Destroy();
File.Delete(this.dsdFile);
}
}
private bool TryCreateDSD()
{
using (DsdData dsd = new DsdData())
using (DsdEntryCollection dsdEntries = CreateDsdEntryCollection(this.layouts))
{
if (dsdEntries == null || dsdEntries.Count <= 0) return false;
if (!Directory.Exists(this.outputDir))
Directory.CreateDirectory(this.outputDir);
this.sheetNum = dsdEntries.Count;
dsd.SetDsdEntryCollection(dsdEntries);
dsd.SetUnrecognizedData("PwdProtectPublishedDWF", "FALSE");
dsd.SetUnrecognizedData("PromptForPwd", "FALSE");
dsd.SheetType = SheetType.MultiDwf;
dsd.NoOfCopies = 1;
dsd.DestinationName = this.pdfFile;
dsd.IsHomogeneous = false;
dsd.LogFilePath = Path.Combine(this.outputDir, LOG);
PostProcessDSD(dsd);
return true;
}
}
private DsdEntryCollection CreateDsdEntryCollection(IEnumerable<Layout> layouts)
{
DsdEntryCollection entries = new DsdEntryCollection();
foreach (Layout layout in layouts)
{
DsdEntry dsdEntry = new DsdEntry();
dsdEntry.DwgName = this.dwgFile;
dsdEntry.Layout = layout.LayoutName;
dsdEntry.Title = Path.GetFileNameWithoutExtension(this.dwgFile) + "-" + layout.LayoutName;
dsdEntry.Nps = layout.TabOrder.ToString();
entries.Add(dsdEntry);
}
return entries;
}
private void PostProcessDSD(DsdData dsd)
{
string str, newStr;
string tmpFile = Path.Combine(this.outputDir, "temp.dsd");
dsd.WriteDsd(tmpFile);
using (StreamReader reader = new StreamReader(tmpFile, Encoding.Default))
using (StreamWriter writer = new StreamWriter(this.dsdFile, false, Encoding.Default))
{
while (!reader.EndOfStream)
{
str = reader.ReadLine();
if (str.Contains("Has3DDWF"))
{
newStr = "Has3DDWF=0";
}
else if (str.Contains("OriginalSheetPath"))
{
newStr = "OriginalSheetPath=" + this.dwgFile;
}
else if (str.Contains("Type"))
{
newStr = "Type=6";
}
else if (str.Contains("OUT"))
{
newStr = "OUT=" + this.outputDir;
}
else if (str.Contains("IncludeLayer"))
{
newStr = "IncludeLayer=TRUE";
}
else if (str.Contains("PromptForDwfName"))
{
newStr = "PromptForDwfName=FALSE";
}
else if (str.Contains("LogFilePath"))
{
newStr = "LogFilePath=" + Path.Combine(this.outputDir, LOG);
}
else
{
newStr = str;
}
writer.WriteLine(newStr);
}
}
File.Delete(tmpFile);
}
[CommandMethod("PlotPdf")]
public void PlotPdf()
{
Database db = HostApplicationServices.WorkingDatabase;
short bgp = (short)Application.GetSystemVariable("BACKGROUNDPLOT");
try
{
Application.SetSystemVariable("BACKGROUNDPLOT", 0);
using (Transaction tr = db.TransactionManager.StartTransaction())
{
List<Layout> layouts = new List<Layout>();
DBDictionary layoutDict =
(DBDictionary)db.LayoutDictionaryId.GetObject(OpenMode.ForRead);
foreach (DBDictionaryEntry entry in layoutDict)
{
if (entry.Key != "Model")
{
layouts.Add((Layout)tr.GetObject(entry.Value, OpenMode.ForRead));
}
}
layouts.Sort((l1, l2) => l1.TabOrder.CompareTo(l2.TabOrder));
string filename = Path.ChangeExtension(db.Filename, "pdf");
MultiSheetsPdf plotter = new MultiSheetsPdf(filename, layouts);
plotter.Publish();
tr.Commit();
}
}
catch (System.Exception e)
{
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
ed.WriteMessage("\nError: {0}\n{1}", e.Message, e.StackTrace);
}
finally
{
Application.SetSystemVariable("BACKGROUNDPLOT", bgp);
}
}
}
}
Heads up. The method, PostProcessDSD, tests are too generic. Client contacted me complaining that one of his files was not plotting. It was named "SOUTH". The test for "OUT" in the string caused the issue. No errors were thrown. Just a good ol' fashion mystery.
Change all tests to include the "=". ie else if (str.Contains("OUT=")) { ...

multithreading programming

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);
}

Categories

Resources