Openlabel Method in parallel threads

Label printing integration (NiceWatch middleware and ActiveX programming interface)

Moderators: Georges, milos, NiceLabel Support Team

Post Reply
margy82
Enthusiast
Posts: 20
Joined: Sun Sep 11, 2016 6:14 pm

Openlabel Method in parallel threads

Post by margy82 » Tue Dec 03, 2019 9:50 pm

Hi guys, I need your help. I'm writing a WPF application and I'm trying to Open multiple labels in different threads to speed up loading phase. The problem is that the program crash giving errors about a problem opening a label. Is OpenLabel method usable in parallels threads?

Thanks

User avatar
Mytch
NiceLabel Support
NiceLabel Support
Posts: 103
Joined: Fri Jul 13, 2018 10:26 pm
Location: Milwaukee, Wisconsin
Contact:

Re: Openlabel Method in parallel threads

Post by Mytch » Wed Dec 04, 2019 9:00 pm

margy82,

Can you explain how you are creating multiple threads and maybe small sample of code? Also, what is the error message you receive?

I just tried with with System.Threading by initializing print engine, open label, print label (async) on main thread. Then created new thread doing the same but printing different label. No errors. I also tried again by using Task.Factory with multiple new tasks and executed all at the same time and had no issues. This way, print engine is initialized one time, and each tasks opens then prints a different label. Each method resulted in continuous printing.

Regards,
Mytch

margy82
Enthusiast
Posts: 20
Joined: Sun Sep 11, 2016 6:14 pm

Re: Openlabel Method in parallel threads

Post by margy82 » Wed Dec 04, 2019 9:06 pm

Mytch wrote:
Wed Dec 04, 2019 9:00 pm
margy82,

Can you explain how you are creating multiple threads and maybe small sample of code? Also, what is the error message you receive?

I just tried with with System.Threading by initializing print engine, open label, print label (async) on main thread. Then created new thread doing the same but printing different label. No errors. I also tried again by using Task.Factory with multiple new tasks and executed all at the same time and had no issues. This way, print engine is initialized one time, and each tasks opens then prints a different label. Each method resulted in continuous printing.

Regards,
Mytch
Hi Mytch, the problem is that I need to use OpenLabel method in parallel threads to speed up loading phase. PrintAsync of more labels already opened works well but I need to previously open those label more quickly. I use System.Threading, but I tried also with Task Factory and Background Worker with the same results

User avatar
Mytch
NiceLabel Support
NiceLabel Support
Posts: 103
Joined: Fri Jul 13, 2018 10:26 pm
Location: Milwaukee, Wisconsin
Contact:

Re: Openlabel Method in parallel threads

Post by Mytch » Thu Dec 05, 2019 10:35 pm

margy82 wrote:
Wed Dec 04, 2019 9:06 pm
Hi Mytch, the problem is that I need to use OpenLabel method in parallel threads to speed up loading phase. PrintAsync of more labels already opened works well but I need to previously open those label more quickly. I use System.Threading, but I tried also with Task Factory and Background Worker with the same results
Margy,

I'm not sure what the problem could be, because I am also using ILabel label = PrintEngineFactory.PrintEngine.OpenLabel on each thread then printing asynchronously. Maybe someone else has input... but probably not. I recommend that you post your exact error message and show how you are creating new threads and opening label.

Mytch

margy82
Enthusiast
Posts: 20
Joined: Sun Sep 11, 2016 6:14 pm

Re: Openlabel Method in parallel threads

Post by margy82 » Fri Dec 06, 2019 8:23 am

Mytch wrote:
Thu Dec 05, 2019 10:35 pm
margy82 wrote:
Wed Dec 04, 2019 9:06 pm
Hi Mytch, the problem is that I need to use OpenLabel method in parallel threads to speed up loading phase. PrintAsync of more labels already opened works well but I need to previously open those label more quickly. I use System.Threading, but I tried also with Task Factory and Background Worker with the same results
Margy,

I'm not sure what the problem could be, because I am also using ILabel label = PrintEngineFactory.PrintEngine.OpenLabel on each thread then printing asynchronously. Maybe someone else has input... but probably not. I recommend that you post your exact error message and show how you are creating new threads and opening label.

Mytch
Hi Mytch, here is the code:

Code: Select all

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading;
using NiceLabel.SDK;

namespace NiceLabelTest
{
    class Program
    {
        private static IPrintEngine printEngine = PrintEngineFactory.PrintEngine;
        private static int initialCapacity = 101;
        private static int numProcs = Environment.ProcessorCount;
        private static int concurrencyLevel = numProcs * 2;
        private static ConcurrentDictionary<string, ILabel> labelsDictionary = new ConcurrentDictionary<string, ILabel>(concurrencyLevel, initialCapacity);

        static void Main(string[] args)
        {
            List<Thread> threads = new List<Thread>();
            List<string> labelsType = new List<string>() { "ROLLO", "TUBO", "SCATOLA", "DETTAGLIO" };
            PrintEngineFactory.SDKFilesPath = @"C:\Program Files\NiceLabel\NiceLabel 2017\bin.net";
            printEngine.Initialize(); // inizializza il motore di stampa
            foreach (string s in labelsType)
            {
                Thread t = new Thread(() => { OpenLabels(s); })
                {
                    IsBackground = true
                };
                t.Start();
                threads.Add(t);
            }

            foreach (Thread thread in threads)
            {
                thread.Join();
            }
            foreach (string key in labelsDictionary.Keys)
            {
                Console.WriteLine(labelsDictionary[key].Variables["Commessa"].Length); // example to check if labels are opened
            }
            printEngine.Shutdown();
            Console.WriteLine("Fine...");
            Console.ReadLine();
        }

        private static void OpenLabels(string labelType)
        {
            ILabel label = printEngine.OpenLabel(@"C:\ProgramData\LabelManager\Labels\" + labelType + "_COMMESSA.nlbl");
            labelsDictionary.GetOrAdd(labelType, label);
        }
    }
}

And here the errors:

Code: Select all

DetailedErrorCode "StorageErrorCode.ErrorReadingFile"

string DetailedMessage "Impossibile aprire il file \"C:\\ProgramData\\LabelManager\\Labels\\ROLLO_COMMESSA.nlbl\" in quanto vi sono problemi con il contenuto. Errore nella lettura dal file. Messaggio di errore di sistema: Riferimento a un oggetto non impostato su un'istanza di oggetto."	

string ErrorCode LabelLoadError	NiceLabel.SDK.SDKErrorCode


User avatar
Mytch
NiceLabel Support
NiceLabel Support
Posts: 103
Joined: Fri Jul 13, 2018 10:26 pm
Location: Milwaukee, Wisconsin
Contact:

Re: Openlabel Method in parallel threads

Post by Mytch » Fri Dec 06, 2019 8:00 pm

Margy,

Thanks for that. I took a quick look and issues only seem to be related to labelType list and labelsDictionary that is used for setting label paths:
screenshot_16.jpg
screenshot_16.jpg (75.86 KiB) Viewed 83 times
If full label path is used with printEngine.OpenLabel, there are no errors and application completes fine (as long as Commessa variable exists, I had to create that otherwise result was null object reference). I see you also get this error, so of course, make sure the variable exists. Maybe I've done something else wrong, though? Not sure if this is really NiceLabel related problem, but it seems you are close to getting this working and not limited by opening labels on a single thread.

I'll try to take another look at your collection syntax again when there's some time. Please let me know if you figure it out in the meantime.

Regards,
Mytch

margy82
Enthusiast
Posts: 20
Joined: Sun Sep 11, 2016 6:14 pm

Re: Openlabel Method in parallel threads

Post by margy82 » Fri Dec 06, 2019 8:43 pm

I Mitch, the variable "Commessa" esists, the crash happens before accessing variable (It is only a simple example) , it appears when OpenLabel method is invoked. Everything works well if I open labels one by one in a foreach loop and store them in a dictionary for later access. It is very strange. I Aldo use ConcurrentDictionary to work in a thread-safe environment. I continue my tryouts

Thanks

margy82
Enthusiast
Posts: 20
Joined: Sun Sep 11, 2016 6:14 pm

Re: Openlabel Method in parallel threads

Post by margy82 » Fri Dec 06, 2019 9:37 pm

Additional info...Non every crash happens with the same label. It occurs randomly to all labels. I try putting openlabel in a try/catch statement and sometimes it crash on a label, sometimes on 2 labels. It seems that printEngine can't use OpenLabel method in multiple parallel threads

User avatar
Mytch
NiceLabel Support
NiceLabel Support
Posts: 103
Joined: Fri Jul 13, 2018 10:26 pm
Location: Milwaukee, Wisconsin
Contact:

Re: Openlabel Method in parallel threads

Post by Mytch » Fri Dec 06, 2019 9:56 pm

margy82 wrote:
Fri Dec 06, 2019 9:37 pm
Additional info...Non every crash happens with the same label. It occurs randomly to all labels. I try putting openlabel in a try/catch statement and sometimes it crash on a label, sometimes on 2 labels. It seems that printEngine can't use OpenLabel method in multiple parallel threads
Okay, so maybe in this case we involve some developers for an opinion.. they do not often monitor these Forums. I will put in some inquiry on your behalf and find out if this is supported. Please allow a few days for further input.

margy82
Enthusiast
Posts: 20
Joined: Sun Sep 11, 2016 6:14 pm

Re: Openlabel Method in parallel threads

Post by margy82 » Fri Dec 06, 2019 10:07 pm

Ok Mytch, thank you for your patience

User avatar
Mytch
NiceLabel Support
NiceLabel Support
Posts: 103
Joined: Fri Jul 13, 2018 10:26 pm
Location: Milwaukee, Wisconsin
Contact:

Re: Openlabel Method in parallel threads

Post by Mytch » Fri Dec 06, 2019 11:28 pm

One quick thing...

What if you try to comment printEngine.Shutdown(); and then try to print async. I actually just changed two small things and everything works and prints:

Code: Select all

foreach (Thread thread in threads)
            {
                thread.Join();
            }
            foreach (string key in labelsDictionary.Keys)
            {
                labelsDictionary[key].PrintAsync(1);
            }
            //printEngine.Shutdown();
            Console.WriteLine("Fine...");
            Console.ReadLine();
Maybe issue was shutting down print engine too soon. Is this working for you?

margy82
Enthusiast
Posts: 20
Joined: Sun Sep 11, 2016 6:14 pm

Re: Openlabel Method in parallel threads

Post by margy82 » Sat Dec 07, 2019 8:10 am

Mytch the problem is that application crash before arriving to printAsync invoke. The strange thing is that sometimes the crash does not occurs. It is certainly related to some printengine resource ( linked to iLabel) that is not thread-safe.

margy82
Enthusiast
Posts: 20
Joined: Sun Sep 11, 2016 6:14 pm

Re: Openlabel Method in parallel threads

Post by margy82 » Tue Dec 10, 2019 10:02 pm

Still no luck with my tryouts. I tried almost everything. Using threads, tasks, putting a Sleep() before shutting down printengine. No way. It is not stable. Any news from devs?

Post Reply