How to use ThermalLabel SDK in ASP.NET or Web Services projects (MTA threading model)

You can use the ThermalLabel SDK dll in ASP.NET or Web Services to generate or print barcode labels. Suppose you want to generate barcode labels in PDF or some raster image format to save it on server disk or to display them in an ASP.NET webpage. You could do that with the following code inside the Load event of a Page:

VB

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

	'Create the thermal label object
	Dim tLabel As New ThermalLabel(Neodynamic.SDK.Printing.UnitType.Inch, 4, 4)

	Dim txtItem As New TextItem(0.2, 0.2, 1, 0.5, "Thermal Label Test")
	
	Dim bcItem As New BarcodeItem(0.2, 1, 2, 1, BarcodeSymbology.Code128, "1234567890")
	'Set bars height to 1 inch 
	bcItem.BarHeight = 1
	'Set bars width to 0.01 inch 
	bcItem.BarWidth = 0.01
	
	 'Add items to the label
	tLabel.Items.Add(txtItem)
	tLabel.Items.Add(bcItem)
	
	'Create a PrintJob object and export the label to PDF
	Using pj As New PrintJob()
	    pj.ExportToPdf(tLabel, "C:\BarcodeLabel.pdf", 300)
	End Using

End Sub

C#

protected void Page_Load(object sender, EventArgs e)
{
        //Create the thermal label object
	ThermalLabel tLabel = new ThermalLabel(Neodynamic.SDK.Printing.UnitType.Inch, 4, 4);

	TextItem txtItem = new TextItem(0.2, 0.2, 1, 0.5, "Thermal Label Test");
	
	BarcodeItem bcItem = new BarcodeItem(0.2, 1, 2, 1, BarcodeSymbology.Code128, "1234567890");
	//Set bars height to 1 inch 
	bcItem.BarHeight = 1;
	//Set bars width to 0.01 inch 
	bcItem.BarWidth = 0.01;
	
	//Add items to the label
	tLabel.Items.Add(txtItem);
	tLabel.Items.Add(bcItem);
	
	//Create a PrintJob object and export the label to PDF
	using (PrintJob pj = new PrintJob())
        {
	    pj.ExportToPdf(tLabel, @"C:\BarcodeLabel.pdf", 300);
	}
}

As soon you test this code, it is likely you get this error:

“The calling thread must be STA, because many UI components require this”

The error is because ThermalLabel SDK is based on the .NET client framework classes which require an STA (Single-Threaded Apartments) Thread and ASP.NET uses a multithreaded apartment (MTA) threading model instead.

So, to use ThermalLabel SDK in MTA environments, you have two choices:

  1. The simplest solution is to set up the AspCompat attribute to “true” of the ASP.NET webpage where you are using ThermalLabel SDK.
  2. The other solution (mainly if you are not using ThermalLabel SDK inside an ASPX page but, for instance, in an ASHX HTTP Handler) is you use ThermalLabel SDK classes inside a STA Thread as shown in the following code:

    VB

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    
    	Dim worker As New Threading.Thread(New Threading.ThreadStart(AddressOf Me.ThermalLabelWorker))
    	worker.SetApartmentState(Threading.ApartmentState.STA)
    	worker.Name = "ThermalLabelWorker"
    	worker.Start()
    	worker.Join()
    
    End Sub
    
    Private Sub ThermalLabelWorker()
    
    	'Create the thermal label object
    	Dim tLabel As New ThermalLabel(Neodynamic.SDK.Printing.UnitType.Inch, 4, 4)
    	Dim txtItem As New TextItem(0.2, 0.2, 1, 0.5, "Thermal Label Test")
    	
    	Dim bcItem As New BarcodeItem(0.2, 1, 2, 1, BarcodeSymbology.Code128, "1234567890")
    	'Set bars height to 1 inch 
    	bcItem.BarHeight = 1
    	'Set bars width to 0.01 inch 
    	bcItem.BarWidth = 0.01
    	
    	 'Add items to the label
    	tLabel.Items.Add(txtItem)
    	tLabel.Items.Add(bcItem)
    	
    	'Create a PrintJob object and export the label to PDF
    	Using pj As New PrintJob()
    	    pj.ExportToPdf(tLabel, "C:\BarcodeLabel.pdf", 300)
    	End Using
    
    End Sub
    

    C#

    protected void Page_Load(object sender, EventArgs e)
    {
            Thread worker = new Thread(new ThreadStart(this.ThermalLabelWorker));
            worker.SetApartmentState(ApartmentState.STA);
            worker.Name = "ThermalLabelWorker";
            worker.Start();
            worker.Join();
    }
    
    private void ThermalLabelWorker()
    {
            //Create the thermal label object
    	ThermalLabel tLabel = new ThermalLabel(Neodynamic.SDK.Printing.UnitType.Inch, 4, 4);
    
    	TextItem txtItem = new TextItem(0.2, 0.2, 1, 0.5, "Thermal Label Test");
    	
    	BarcodeItem bcItem = new BarcodeItem(0.2, 1, 2, 1, BarcodeSymbology.Code128, "1234567890");
    	//Set bars height to 1 inch 
    	bcItem.BarHeight = 1;
    	//Set bars width to 0.01 inch 
    	bcItem.BarWidth = 0.01;
    	
    	//Add items to the label
    	tLabel.Items.Add(txtItem);
    	tLabel.Items.Add(bcItem);
    	
    	//Create a PrintJob object and export the label to PDF
    	using (PrintJob pj = new PrintJob())
            {
    	    pj.ExportToPdf(tLabel, @"C:\BarcodeLabel.pdf", 300);
    	}
    }
    

  3. Advertisements

5 Responses to How to use ThermalLabel SDK in ASP.NET or Web Services projects (MTA threading model)

  1. Jaans says:

    Thanks… that helps loads!

    Having a major problem with handling of exceptions thrown in the worker thread in that it crashes the whole application. How do I prevent that from happening?

    Ps: If it’s not in a work thread this problem doesn’t happen

    • neodynamic says:

      Hi Jaans,

      What is the error you get there? Please contact our Tech Support elaborating more about your scenario and other details. Thanks,

      • Jaans says:

        The issue we are having is that exceptions (any kind) that are thrown inside the worker thread is not raised to the calling thread where the thread.Join() is waiting for the thread to complete/abort.

        Bottomline, the calling code that initiates this thread, is unaware of exceptions thrown by the worker and cannot perform any compensatory work in response to the exception.

        PS: We’re using .NET 4.0

      • neodynamic says:

        This http://miteshsureja.blogspot.com/2011/09/how-to-handle-exceptions-while-working.html may help you. And the other option you have is to move your code from an ASHX file to an ASPX with the AspCompat attribute set to “true” avoiding in this case the Threading code.

      • Jaans says:

        Thanks for the link and the help.
        The link simply confirms the issue, in that the exception on the worker thread is only caught on that worker thread and that the calling thread that started the worker thread will remain blissfully unaware (and unable to rollback the transaction for example).

        The issue is about being able to tell the calling thread that something went wrong in the worker thread.

        It’s become clear that I will need to implement thread synchronisation to share data between the calling thread and the worker thread in order to “signal” back to the caller some sort of result. Once the thread.Join() unblocks I can then check this “signal” and act accordingly.

        Thanks

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: