Driverless SDK & Multi-thread

We are trying to use Driverless SDK for ZXP 1 and ZXP 3, to monitor and printing over LAN/WAN networks in parallel mode.

 

 

To do this, we think we should implement Multi-thread so Our application can work with different printers at same time.

 

 

We have test it unsuccessfully, one task on one printer have to finish so another task can start in another printer. If we running theses task in parallel in two printers, we get weird behaviors on the them.

 

 

We have not been able to be printing on one printer, while in the other one detecting a card (CARD READY) and reading its track. It's like printer handlers gets mixed up.

 

 

Is any suggestion about how to proceed?

Our application is being develop on C# .Net.

Stephen Troup
I've had singular printers

I've had singular printers working on background threads but as the zxpprinter.dll is a com object I'd suggest

setting the individual threads to STA as by default .net will set them to MTA by using threadname.SetApartmentState(ApartmentState.STA) before starting them.

The zxpprinter.dll is marked as apartment so trying to run with MTA threading is probably causing all the messages to get confused and routed to the wrong object and causing the problem i.,e. zxpprinter is not threadsafe. Each thread must initialize it's connection to the object.

If I have the time I'll try to do something similar to what you have here but using the library for the zxp 7,8,9 printers which operates similarly.

edit:

Just confirmed that the async await methods also use a MTA thread rather than STA. To use STA a different task scheduler is required. I've found one but not tested it extensively other than checking to see if the async task is running in MTA or STA.

A Custom TaskScheduler for STA-Threads - Journey of Code

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Ian Espiga
Thanks, we also have tested.

Thanks, we also have tested. We found we have to launch different task scheduler for each printer.

Anyhow, still doesn't comply with the idea we want to implement.

Can you share your sample code, for this testing?

Thanks

Ian.

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Stephen Troup
Excuse the VB code. This uses

Excuse the VB code. This uses the STA thread handling library from the link above. I wrote this in vs2015. I've only got the usb ZXP3 available to me but I've tried it on ethernet with a ZXP 7,8 and 9 with my libraries for those. Clicking the first button and then the second should result in both printers performing the same function at the same time.

I've cropped this from test app so it won't work by pasting directly into another but it might help.

    Private Async Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click

       Dim printer as string = "192.168.1.20:9100" ' network only needs the ip and port

        Dim th1 As New journeyofcode.Threading.SingleThreadTaskScheduler(Threading.ApartmentState.STA)

        Dim j1 As New Task(Of Boolean)(Function()

                                           Return MoveandEject(printer, tbltest.Rows(0)) 'only does the move and eject but this

                                       End Function)

        j1.Start(th1)

        Await j1

        Label1.Text = j1.Result.ToString

        j1.dispose

        th1.dispose.

    End Sub

    Private Async Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click

       Dim printer as string = "192.168.1.21:9100"' network only needs the ip and port

        Dim th1 As New journeyofcode.Threading.SingleThreadTaskScheduler(Threading.ApartmentState.STA)

        Dim j1 As New Task(Of Boolean)(Function()

                                           Return MoveandEject(printer, tbltest.Rows(0)) 'only does the move and eject but this

                                       End Function)

        j1.Start(th1)

        Await j1

        Label1.Text = j1.Result.ToString

        j1.dispose.

        th1.dispose

    End Sub

'generic routine to do the move and eject

    Public Function MoveandEject(ByVal printer As String, ByRef dr As Data.DataRow) As Boolean

        Dim j As New ZMotifZXP.ZMotifZXP3(Of Data.DataRow)(printer) 'my library for the ZXP3 range that initializes and hides the com objects to the rest of my application

        Dim pass As Boolean

        j.Feeder = ZMotifZXP.ZMotifZXP3.FeederSourceType.CardFeeder

        j.Destination = ZMotifZXP.ZMotifZXP3.DestinationType.Eject 'normally this would be the internal hold but this test code doesn't print.

        j.ContactlessSmartCard(pass, dr) 'move one card from the feeder to the contactless position and then encode. This code waits for the printer to finish it's actions before returning

              

        j.Dispose() ' closes the connection and cleans up the com objects.

        Return True

    End Function

tbltest is a standard datatable that had one row of data . The zmotifzxp3 class holds all the com objects for me and hides them all from the rest of the app, it's based losely on code that came in the sdk notes.

I threw this code together just to test the async routines

Trying to do multiple tasks with the same journeyofcode.Threading.SingleThreadTaskScheduler(Threading.ApartmentState.STA) object will result in them being performed the sequentially not in parallel. So if you need to do multiple calls in the same routine you'll need one for each printer.

The system.windows.forms.timer eventhandler can also be made to work with the Async but it can trigger multiple times simultaneously.

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Log in to post comments