Dmitry Kostochko

HowTo: Work with threads in Microsoft Office COM add-ins

It is generally known that the Microsoft Office Object Model is not thread safe and accessing some object, property or method not from the main thread of a COM add-in may sometimes result in a host application crash. Of course, nobody prevents you from using threads inside the Office COM add-in itself, the threads that don’t need the Office Object Model.

In our today’s VB.NET example (a C# sample is available for download at the bottom of the page), we are going to fill in the DataGridView component, which is located in the Outlook Explorer window, with data by using a background thread. Here’s the code that runs the thread and adds a hundred lines to the DataGridView.Rows collection:

Private Sub startButton_Click(ByVal sender As System.Object, _
  ByVal e As System.EventArgs) Handles startButton.Click
    startButton.Enabled = False
    myThread = New Thread(AddressOf StartThread)
    myThread.Start()
End Sub
 
Private Sub StartThread()
    SyncLock ThreadRunningObj
        FlagThreadRunning = True
    End SyncLock
    Try
        Dim nameColumn As String
        Dim timeStamp As String
        Dim boolColumn As Boolean = True
        For i As Integer = 1 To 100
            nameColumn = "Record " & i.ToString()
            timeStamp = DateTime.Now.ToString()
            boolColumn = Not boolColumn
            AddRow(nameColumn, timeStamp, boolColumn)
            Thread.Sleep(1000)
            If Not FlagThreadRunning Then
                Exit Try
            End If
        Next
        SetEnabled(True)
    Finally
        SyncLock ThreadRunningObj
            FlagThreadRunning = False
        End SyncLock
    End Try
End Sub

Naturally, besides launching we need to stop the thread. Let’s do it with some stop button:

Private Sub stopButton_Click(ByVal sender As System.Object, _
  ByVal e As System.EventArgs) Handles stopButton.Click
    StopThread()
    startButton.Enabled = True
End Sub
 
Private Sub StopThread()
    SyncLock ThreadRunningObj
        FlagThreadRunning = False
    End SyncLock
    myThread.Join()
End Sub

One more note. You have to stop the additional thread not only upon clicking the Stop button, but also when closing the host application. In our sample, it should be done in the Dispose method:

Protected Overloads Overrides Sub Dispose( _
  ByVal disposing As Boolean)
    If disposing Then
        If myThread IsNot Nothing Then
            StopThread()
        End If
        If Not (components Is Nothing) Then
            components.Dispose()
        End If
    End If
    MyBase.Dispose(disposing)
End Sub

That’s all for today. If you have any questions or comments, don’t hesitate to post them!

You may also be interested in:

How to create Office COM addin in .net
Build COM add-in for Office 2000 – 2007 in Delphi

Available downloads:

C# sample Outlook add-in for VS 2005
VB.NET sample Outlook add-in for VS 2005
Delphi sample Outlook add-in for Delphi 7

4 Comments

  • Chan Chi Keung says:

    How about working with delphi 7 or 2009 ? I want to get an example similar to dot net.

    Thanks your add in express.

  • Dmitry Kostochko (Add-in Express Team) says:

    There is one quite serious problem in Delphi. The TThread.Synchronize method does not work in a DLL. That is why “normal” synchronization is not possible. But you can use the PostMessage function to notify the main VCL UI thread that some changes were made in a background thread. Please see the new Delphi sample under Available downloads.

  • Paul says:

    Would it warrant mentioning the .NET BackgroundWorker? Does using BackgroundWorker always ensures marshaling back to “UI” thread of the host application?

  • Dmitry Kostochko (Add-in Express Team) says:

    In these samples we don’t use the BackgroundWorker class. Of course, you can try to use it, but I am afraid you will have to synchronize manually.

Post a comment

Have any questions? Ask us right now!