3 Replies Latest reply on Apr 20, 2017 4:03 AM by Stephen Troup

    Driverless SDK & Multi-thread

    Ian Espiga

      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.

        • Re: Driverless SDK & Multi-thread
          Stephen Troup

          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

          • Re: Driverless SDK & Multi-thread
            Stephen Troup

            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.