Jump to content

Multi Thread .net Driver


Recommended Posts

Good morning,

I'm reviewing the .net verision of the Com Drive, I've got an applicaiton that requires serial communication between the PC and the PLC occur on a seperate thread from the UI due to performance concerns.

Has anyone done this successfuly and would you be willing to share the .net class code?

Thanks a million, any help would get me out of a pickel.


Link to comment
Share on other sites

The .Net driver has the ReadWrite functions with an overload that works with IAsyncResult.

In my opinion, it is not easy to work with microsoft IAsyncResult because it requires splitting your code into 2. The .Net driver does do the communication on another thread, but it is blocking the calling thread up until it got a reply or the timeout and retires passed.

I will help you with your request when I'm back to work. For that, I need to know if you are working with WinForms or WPF.

Link to comment
Share on other sites

Ok, I understand that it is a WinForms program. I saw on your email that you are using VB.Net

I don't know which version of .Net you are using

There are some differrences between VB.Net and C#, mostly in syntax, but C# 3.5 supports something called Anonymous Method which VB.Net doesn't (I think that in .Net 4.0 VB.Net also capable of this feature).

If you can switch to C#, it would be better for both of us.

I've attached a small example that shows how to read and write files from SD Card using the communication driver and doing in on a differernt thread (If it was on the UI thread, then after 5 seconds, the program would become "Not Responding").

As for the questions you've asked in your email:

Question 1 –

Can I setup a multithreaded application with the PLC via the serial port , i.e a separate read and a second write thread

Will I generate any collisions as a result of that?

Answer: You can setup a seperate thread for read and a seperate thread for write, but it would be useless. The Communication driver works Syncronously with the PLC, meaning: it can't do read and write at the same time... In fact, it is not just read and write... it can't handle 2 communications at the same time.

This is why the Communication driver has a queue that collects your requests and does it one by one.

So.. there won't be any collisions, and several threads will only reduce the performance.

Question 2-

Would you be able to provide me with a Class of sample code illustrating a multithread situation?

Yes.. I've provided one... I will also explain a little more.

Ok, lets start talking about UI and multithreaded applications. Here are some pseudo code:

Button Click:

Disable some of the UI depending on what you want to do (For example, when you click on "Read File From SD" you don't want to be able to Delete, or write some other files, so you disable those buttons.

You create a thread (Or a Task, if you are using .Net 4.0) that invokes the following code:

1) Reads data from PLC (lets assume it take 5 seconds to accomplish this action).. Since we are not doing it in the UI thread, so it is not "not responding"

2) Now we want to update the UI... we create a delegate and call the UI.Invoke with that delegate (for example, this.Invoke if the code is now running in the Form)

3) We perform Data writing to the PLC

4) Update the UI again (for example percentage), again using this.Invoke

5) Now update the UI again in order to enable buttons/UI that we have disabled at the begining, using the this.Invoke

If I know in what .Net framework you are working, then I can be more specific in my code.

SD Card Explorer Lite - Example.zip

Link to comment
Share on other sites

Here is a code example that shows how to work with 2 threads (using .Net 4.0 Task in VB.Net):

Public Class Form1
   Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    Button1.Enabled = False
    Label1.Text = "Starting Long work"
    ProgressBar1.Value = 0
    Dim action As Action
    action = Sub()
				 Dim uiAction As Action
				 Dim index As Integer
				 For index = 0 To 100
					 ' Do some work that takes time
					 ' Update the UI with the results
					 uiAction = Sub()
								    Label1.Text = "Working... " & index & "%"
								    ProgressBar1.Value = index
							    End Sub

				 uiAction = Sub()
							    Button1.Enabled = True
							    Label1.Text = "Done"
							    ProgressBar1.Value = 100
						    End Sub
			 End Sub
   End Sub

   Private Sub updateUI(action As Action)
    If (Me.InvokeRequired) Then
	    Call action()
    End If
   End Sub
End Class

Link to comment
Share on other sites

Thank you for the reply.

The application is a winforms proejct written in VB on the .net 4 Framework,

using the .net version of the untronics Driver

The reason this is an issue is I need to monitor PLC inputs such as an E-Stop for example, by the PC interface every .5 sec.

This continual monitor loop is causing a massive impact on the UI performance as you can well imagine.

First thought is to create a read only dataset or datatable for each PLC datatype, for example (ReadInputs, ReadOutputs, ReadMI, ReadMB, etc.) on a background worker thread that's dedicated to monitoring the PLC and exectue a update every .5 sec.

Using the rowchanged event on the main IU thread against these tables to get the state of the PLC I/O MI/MB, etc.

This would prevent the main UI thread from needless looping through the PLC inputs to see what's changed.

If this is feasible could there be a second set of tables, for example WriteInput, WriteMI, WriteMB, etc, that would receive the changes from the UI thread and again using the row changed event to write these values back to the PLC as a "Batch", possibly bundling the read with the write events every .5 seconds to send back to the PLC.

I realize there may be slight latency issues with the serial port.

Am I making this more complicated that it needs to be?

Thank you again for you guidence and patience!

Link to comment
Share on other sites

No, it looks OK.

I don't know how many Operands are you reading, but note that if you read too much, then the time it takes to read them all could exceed 0.5 seconds.

Also, you don't need to send several requests to the PLC (1 for reading inputs, one of reading outputs, one for MIs, one of MBs etc)... You can create use 1 ReadWrite call and give it an array of ReadWriteRequest that contains all the reads (you can also give it write requests).

The communication driver would joins and split them to several requests of needed (if the sent or the received data exeeds the rt/tx buffer of the plc).

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...