tags:

views:

877

answers:

3

Hello,

My problem: I have DataReceived event for SerialPort, which listens to serial port and appends everything to RichTextBox. Now I'd like to save RichTextBox's content to txt file. I could do this:

string text = RichTextBox.Text;
// save file
RichTextBox.Clear();

But I fear (and please correct me if I am wrong), that just between my two actions (save content to variable, clear RichTextBox) another input could come to SerialPort. Because I didn't saved it to my variable and I clear RichTextBox right after it, this new data could be deleted, without me even knowing that it ever existed.

Could this really happen and how can I avoid it?

Thanks

A: 

This could happen if you are using multiple threads. In a single thread application, this problem would not occur.

To prevent this, you can use mutex. This is how it works: The code snippets that work on the contents of RichTextBox should not be executed concurrently. These code snippets are called critical sections. When you enter a critical section, you lock the mutex and release it when exiting the critical section. If a mutex is locked when you try to enter a critical section, wait until that mutex is released, and then do your job.

This way, if any input comes through the serial port while writing to the file, the thread recieving the data will wait until the file I/O is finished and then append it to the RichTextBox.

You can achieve this by using the lock statement in c#.

Further reading: Mutex, Critical Section

erelender
DIY synchronizing won't work, the Controls check ThreadId and throw. You __have__ to use Invoke().
Henk Holterman
+2  A: 

You have to synchronize your Inputs from the Serial port somehow. I assume you use Invoke in the DataReceived event. So any changes to the contents of the RichTextBox are done by the main thread and you should be safe.

But as the stream from the serial port is unlikely to be RTF (you would have other problems if it was), you might as well use a TextBox (MultLine=true).

Henk Holterman
I write to RichTextBox with Invoke (from DataReceived thread), so writing and reading is in same thread (GUI). That means, that my scenario could not occur?
_simon_
At first glance, I didn't think using Invoke would protect you, but now that I've thought this through, this would protect you. Good answer! +1
David Stratton
I use RichTextBox because I check every input from serial port in SQL and get back his status. If status is 'OK', then text color for this input is green, if not ok, text color is red. So operator can easily see if input is OK or not OK...
_simon_
A: 

Absolutely that could happen (and probably would).

Unless there are other considerations, I believe that you would be better served using the data from the SerialPort stream to write the text file directly, rather than writing to the file using the RichTextBox.Text. The DataReceived event handler should look something like this...

private void SerialPort1.DataReceived(object sender, SerialDataReceivedEventArgs e)
{
   string DataText = // code to read the serialport data and convert 
   //it into a string, which you already have so I 
   //won't repeat it here.

   WriteToTextBox(DataText);
   WriteToFile(DataText);
}
David Stratton
In DataReceived event I first write text to SQL database, then show it in RichTextBox, so that the operator can see on screen what was scanned. Saving to text file is just another option for operator (if something is not ok, he can just save text to file and send it to administrator).
_simon_