C# forms app serialport multi-write without proper read - c#

I am using serialport in forms. My pc is linked with a external device through serialport.
I try to multi-write a sequence of data into the device with feedback read.
When I write the data one by one through mouse click, everything is good. But when I try to write-wait-read-write-wait-read.... in one thread. The feedback read comes back in a cluster of data at the end of the write instead of after every write.
my code looks like this
void button click write and read
{
serialport.write
wait
read
write
wait
read
...
}
I tried to invoke read function in the function and multi-thread read. But it doesn't seem to work. I guess the thread processes the main loop before processes all the reads functions.
My idea to fix this is to tail write function to the read function.
Anyone knows how the thread prioritizes function? Or a better idea to fix this?
Thanks

Related

Best way to let multiple .NET apps communicate with each other

So, first of all sorry for my bad english.
Back to the questio, i have a main app, with a tab control, each tab contain another .NET exe. These need to send infos to the main app. Example:
Each exe in a tab have a random generated guid every second and the main app need to catch this and show in a listview or something as long the exe is "alive".
Currently i'm using SQLite, and everytime a new exe is started this one write in a table. Before closing it this exe remove the recod from the table.
In the mainwhile, the main app retrieve this update table and show the "alive" exe and the random generated guid (every second). All works fine, the problem is that i need to abandon this method and remove the two dll of SQLite.
What i tried is:
UDP socket between the N clients and the main app, but is not so stable. And sometime some exe got freezed. (using TCP will be so "heavy" for the only purpose to send a short string. Right?)
Changing the window text of the other exe and retrive it via processinfo, but is not updating it, i get it just the first time string.
So, there is a way for that? In local. Like, i don't know.. user32 sendmessage maybe? Or this method is too invasive for just a short string?
Considering that the N sub exe are process "inside" the main one, there is not a way to obtain infos from child process?
Thanks for your help!
UDP does not guarantee delivery of the packet by-desing. Unless you implement your own confirmation protocol above it. But implementation itself should be stable.
Using TCP will provide similar results. You'll just have to deal with reconnect stuff.
SendMessage/PostMessage is the easiest and straight forward method. But it will not allow you to pass string directly. Take a look at RegisterWindowMessage to register your own message and SendMessage with HWND_BROADCAST handle. And you'll have to send pointer to your string. Since SendMessage is synchronous you should be teoreticaly fine with disposing of that message, but I haven't tried that. Another option would be storing string somewhere-else (registry, file) and sending just update notification using SendMessage. And the main app will read and delete that registry/file record.
Self hosted WCF with netNamedPipeBinding should work as well. But that would be propably too robust solution.

Send data from Python to C#

I'm trying to send data from a python script to my c# application using a standard input stream. I also need to eventually send data back from my c# application to the another python script. I first tried to do this with a UDP Connection which works fine for a couple lines, but I have a fair amount of data to send (a few thousand lines) and a requirement for data integrity which UDP cannot provide. I could also write to a file, but that seems very inefficient.
One last restriction is that while my two applications are related I cannot setup a direct connection between them using something like IronPython as they are both spawned separately by a 3rd party application.
This is what I am currently trying, but it is not working. Similar to this question: Passing data between Python and C# without writing a file
p = subprocess.Popen(C_SHARP_EXECUTABLE_FILE_PATH, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)
p.communicate(blob)
On my C# side I'm not entirely sure how to read this data, but I've tried using things like a loop around this:
Console.ReadLine()
or getting the standard input and reading from it directly using:
Console.OpenStandardInput();
The current issue is that as soon as I call p.communicate my Python script gets locked and doesn't proceed. If it's waiting for the line to be read, what do I need to do to make it stop waiting? I tried only providing the stdin parameter, but that didn't help.

File is being used by another Thread

I am reading data from serial port and writing it on text field using Timer event , but when writing those data to file in timer event method or SerialDataReceived method. I get file is being used by another thread.
Even I set FileShare.Write , but still having the same problem.
From your problem description, I think you are trying to write the file from two places Timer event and SerialDataReceived event. So there is a chance of both trying to access the file at the same time. Better and a synchronizing block using lock. It could be better to understand the problem if the source code can be shared.
I changed the algorithm ,usage a Array List for storing the data coming from the
SerialDataRecievedEvent then usage timer event to write into the file !
It worked !

Incomplete Serial Port Read C#

I'm trying to read bytes from a scanner hooked up to a COM port into a byte array. The Serial Port library in C# already has a Read function, this is the function I use to attempt a read. I have it setup so that the bytes read in are output to the console. I'm working with a protocol that is very predictable so I know what kind of byte array I am expecting when I pass that line in the code. However, if I run the program, I only get a single byte read in. If I re-run that same instance of the program (by sending the same read command) I get the rest of the expected bytes. Only after I run this a third time do I get all of the bytes I'm expecting. This problem is completely avoided though if I simply insert a breakpoint over the read line and step over that line. If I do this, I get a complete read every time. My question is, how can I get a complete read every time without inserting a breakpoint? I've tried using the System Pause approach to halt the execution and let the COM port scan fast enough, which did not work. I've also tried using a thread (see code below). This also did not work. Any suggestions?
t = new Thread(() => device.Read(buffer));
t.Start();
t.Join();
Again, my expected output only comes in a full-packet after re-sending the Read command a few times or by stepping over the above commands with a breakpoint. Otherwise I get my expected output in small "byte sized samples." Any help is appreciated!
This is expected behaviour with byte streams. Loop round the read and pump however many bytes received one-by-one into your ProtocolUnit class instance, (or whatever), until it is complete and verified.
I recently posted a similar question found here:
SerialPort.DataReceived Returning Strange Results
The problem is, as you know, the program tries to read from the buffer without any guarantee that the device is finished issuing whatever command it's running. My advice is to implement the first answer in this post:
Reading from the serial port in C#
My implementation is as follows in the DataReceived event:
void serialPort_DataReceived(object s, SerialDataReceivedEventArgs e)
{
byte[] data = new byte[serialPort.BytesToRead];
serialPort.Read(data, 0, data.Length);
Console.Write(System.Text.Encoding.UTF8.GetString(data));
}
And just to wire it up in the code:
serialPort.DataReceived += serialPort_DataReceived;
The best approach to put in while loop and also give 10 millisecond of sleep time in between of byte read. This will give 10 milliseconds to scanner to write data on COM port. Actually, Problem happens when you connect scanner in network port.
You can also write delegate or event which will notify when data is completely read from scanner.

Stalling program until JSFL file finishes

I am trying to run a JSFL script from within a C# project, where the JSFL script opens up a .fla file, modifies it n times, and exports n .swf files before closing. From the C# project, I am starting up the JSFL script through the Process class. I try to wait for the JSFL process to finish through the myProcess.WaitForExit() command, but it doesn't work. The remainder of my code C# executes before the JSFL process finishes exporting its .swf files. Is there any way I can throw something that the C# project can catch from the JSFL file or some other solution?
One solution (although most likely not the best one) would be for your C# code to look for the SWF files being created. Only once they've been updated/created will the JSFL script have finished, so you know that it will be safe for your C# to move on. In case there is no way of knowing how many SWF files the C# program needs to look for, you could instead let the JSFL script write to a log file of some sort, and to have the C# program read that log on a interval, looking for some sort of token to indicate that the JSFL script has completed it's task.
Granted, this may be far from the best method (and I don't know C# well enough to know whether what you're seeing is by design or a sign of something being wrong). But it may just be the case that running JSFL/Flash is completely asynchronous and if so, maybe the log file approach is the quickest path to solving the problem.
I have the same problem with another application that calls an external JSFL script.
What I do is write a file once finished to a target directory, and in the calling application, poll for that file. As soon as the file appears, I know the task has finished, and I delete the temp file, and carry on. Oh - and before starting I look for and delete any temp files so I don't get a false positive.
It's not so nice as events, but you have to work with what you've got.
Have you tried to set a custom Listener that will execute a function when the JSFL done. Don't forget that it's still based on ECMA which is a procedual language.
By the way, JSFL has a LOW-LEVEL C API.
C LEVEL API
This is absolutely possible, and I've already posted a solution here on stack overflow, complete with a detailed problem description and all the C# and JSFL source code necessary to implement it: Automating publishing of FLA files; calling Process.Start multiple times
To summarize... first of all, waiting on the JSFL script process is useless, because you're actually calling Flash.exe, which will remain open/running after the JSFL completes, so you'd be waiting on a process exit event that will never occur.
The trick is to use a JSFL function at the end of the JSFL script which executes a windows command line command, and it's that call which will signal your C# app that the JSLF script has completed. So basically you'll have your main instance of your C# app, but you want to modify your C# app so that a 2nd instance can be run from a command line with a particular switch. When you're C# app is called with a particular switch (from the JSLF file), then instead of running normally, you want your program to simply signal a wait handle in the main instance of your application and then close. I use a simple third-party open-source library called XDMessaging, which facilitates such inter-process communication. It lets you open a named channel in your C# app, which can receive a command from the 2nd instance, signaling the main instance that the JSFL script has finished and it's safe to continue.
But involving file watcher like this is not the best solution so I catch the Flash process and keep watch on the process title and tell the JSFL render some window title for the flash window after finish the execution.

Categories

Resources