Category Archives: .NET Framework

Event Handlers That Do Thread-Safe Invokes

I recently ran into a scenario where I wanted to write a class to do a low-level serial interface to a barcode scanner. When the barcode is scanned I wanted it to fire an event back to the Windows form. The complication was that the SerialPort class provided by .NET 2.0 fires the DataReceived event on an independent thread. In order to fire the event back to the form it needs to be synchronized to run on the thread of the form using the Invoke method.

While this can be done using manual delegates and other methods, they don’t work very cleanly like an actual event handler does for simple development. The fix to this problem is to actually write a custom event handler. The custom event handler implements all of the back end handling that is normally hidden by VB. Here is the example code from the barcode scanner class:

Private _barcodeScannedList As List(Of EventHandler(Of BarcodeScannedEventArgs))
Public Custom Event BarcodeScanned As EventHandler(Of BarcodeScannedEventArgs)
AddHandler(ByVal value As EventHandler(Of BarcodeScannedEventArgs))
If _barcodeScannedList Is Nothing Then
_barcodeScannedList = New List(Of EventHandler(Of BarcodeScannedEventArgs))

End If
_barcodeScannedList.Add(value)

End AddHandler

RemoveHandler(ByVal value As EventHandler(Of BarcodeScannedEventArgs))

If Not _barcodeScannedList Is Nothing Then
_barcodeScannedList.Remove(value)

End If

End RemoveHandler

RaiseEvent(ByVal sender As Object, ByVal e As BarcodeScannedEventArgs)

If Not _barcodeScannedList Is Nothing Then
For Each handler As EventHandler(Of BarcodeScannedEventArgs) In _barcodeScannedList
Dim safeInvoker As ISynchronizeInvoke = TryCast(handler.Target, ISynchronizeInvoke)
If safeInvoker Is Nothing Then
handler.Invoke(sender, e)

Else

safeInvoker.Invoke(handler, New Object() {sender, e})

End If

Next

End If

End RaiseEvent

End Event

The _barcodeScannedList simply stores a list of all of the event handlers that have been registered with the class. AddHandler and RemoveHandler do the process of actually adding and removing those event handlers from the list. The real meat is in the RaiseEvent handler. Instead of simply iterating through the list and firing all of the event delegates directly like the standard handler does, this handler tests to see if the target class of the delegate implements the ISynchronizeInvoke interface. System.Windows.Forms.Control does implement this interface, meaning that all Forms implement it. If this interface is found, then the interface’s Invoke method is used instead of the delegate’s Invoke method. This will synchronize the call onto the delegate’s target’s thread.

Forcing 32-bit Execution in .NET

Sometimes when developing .NET applications it becomes necessary to force an application to run in 32-bit mode, even on a 64-bit processor. One scenario that I’ve run into is when you’re using Crystal Reports embedded in the application. I’m not sure about newer versions, but for Crystal Reports XI R2 it won’t work in 64-bit mode.

In order to get something like that to work, you must force 32-bit execution on the executable. Forcing it on a DLL assembly in your application won’t help, then it won’t be able to load that DLL either. It needs to start in 32-bit mode from the beginning. If you can make the change in the development environment before compilation, just set the flags on the assembly there and everything will be great.

However, if you need to make the change to a compiled assembly it’s a little more difficult. To do so, use the corflags command-line utility. This program is included in the Windows SDK. To do so, simply run “corflags program.exe /32BIT+”.

If the assembly is strongly-named, then you must do a little more. First, you must add a /force flag, running “corflags program.exe /32BIT+ /Force”. Then, you must rehash and resign the assembly, using “sn -Ra program.exe key.snk”. In this case, key.snk is your key file for signing the assembly.

Hope this helps!

Using Transactions With DataSets

One of the major shortcomings of the ADO.NET dataset system, in my opinion, is the lack of support for transactions. In .NET 2.0 this situation was somewhat addressed by the addition of the System.Transactions namespace. However, this namespace has two flaws when it comes to using it with a DataSet. First, if you open more than one database connection within the same TransactionScope, it will use the Distributed Transaction Coordinator (MSDTC) instead of more efficient and configuration free database transactions. Second, if you require backwards compatibility with SQL 2000, it will ALWAYS use the MSDTC even if you open just a single database connection. The first issue can be addressed by opening the connection in advance and passing it to each TableAdapter that you use. Note that you’ll need to change the Connection property on the TableAdapter from Friend (internal) to Public in the DataSet designer if the DataSet is in a DLL.

The second issue is a bit trickier to solve. In this case, you also need to open a single database connection as before, but then use an old fashioned SqlTransaction instead of the System.Transactions namespace. Then both the SqlConnection and SqlTransaction need to be set on each TableAdapter. This can be done by adding a special helper function to the partial class for the TableAdapter, as shown below.

Namespace DataSetTableAdapters

Partial Class TableAdapter

Public Sub SetConnection(ByVal cn As SqlConnection, trans As SqlTransaction)
Connection = cn
For Each cmd As SqlCommand In Me.CommandCollection
cmd.Transaction = trans
Next
Adapter.UpdateCommand.Transaction = trans
Adapter.InsertCommand.Transaction = trans
Adapter.DeleteCommand.Transaction = trans
End Sub

End Class

End Namespace