Setting up a timer in a .NET sample that uses the AutoCAD .NET API

By Balaji Ramamoorthy

 If you want your AutoCAD .NET plug-in to perform some tasks at regular intervals, then it is important to ensure that the timer runs in the AutoCAD’s main UI thread. Implementing the timer in a separate thread does not work because AutoCAD (atleast until 2013 release) does not support multithreaded applications.

To setup a timer to work properly, one possible way is to use a hidden modeless window that in-turn instantiates a timer (use the System.Windows.Forms.Timer). The System.Windows.Forms.Timer differs from the other timers provided by the .Net framework and is guranteed to run in the same UI thread which started it. For a comparison of the various timers available in the .Net framework, you may refer to this MSDN magazine article.

Here is the sample code that displays a tray bubble at a specified time interval :

First lets look at the commands class

Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.Windows
 
 
 
Public Class AdskMyTimerClass
    Implements IExtensionApplication
 
    'System.Threading.Timer is a simple, lightweight timer that 
    'uses callback methods and is served by thread pool threads. 
    'It is not recommended for use with Windows Forms, because 
    'its callbacks do not occur on the user interface thread. 
 
    'System.Windows.Forms.Timer is a better choice for use with 
    'Windows Forms and its callbacks occur on the same UI thread. 
    Private _timerForm As MyForm
 
    Public Sub Initialize() _
        Implements IExtensionApplication.Initialize
        _timerForm = Nothing
    End Sub
 
    Public Sub Terminate() _
        Implements IExtensionApplication.Terminate
        StopTimerMethod()
    End Sub
 
     _
    Public Sub StartTimerMethod()
        If _timerForm Is Nothing Then
            _timerForm = New MyForm
            _timerForm.Show()
            _timerForm.Hide()
        End If
    End Sub
 
     _
    Public Sub StopTimerMethod()
        If _timerForm IsNot Nothing Then
            _timerForm.Close()
            _timerForm.Dispose()
            _timerForm = Nothing
        End If
    End Sub
End Class

Now for the Form class that creates the timer :

Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.Windows
 
Public Class MyForm
 
    Private _myTimer As System.Windows.Forms.Timer
    Private _ti As TrayItem
    Private _icon As System.Drawing.Icon
    Private _cnt As Int32
 
    Private Sub MyForm_Load( _
            ByVal sender As System.Object, _
         ByVal e As System.EventArgs) _
         Handles MyBase.Load
        _myTimer = New System.Windows.Forms.Timer()
        _myTimer.Enabled = True
        _myTimer.Interval = 5000
        AddHandler _myTimer.Tick, AddressOf MyBubbleTimer_Tick
        _myTimer.Start()
    End Sub
 
    Private Sub MyBubbleTimer_Tick( _
            ByVal sender As System.Object, _
            ByVal e As System.EventArgs
                                    )
        _cnt = _cnt + 1
 
        Dim sb As StatusBar = Application.StatusBar
        Dim tis As TrayItemCollection = sb.TrayItems
 
        If _ti Is Nothing Then
            _cnt = 1
            _ti = New TrayItem()
            _ti.Visible = True
            _icon = New System.Drawing.Icon("C:\Temp\spintest.ico")
            _ti.Icon = Icon
            _ti.ToolTipText = "My Timer trigerred bubble !"
            tis.Add(_ti)
            sb.Update()
        End If
 
        _ti.CloseBubbleWindows()
 
        Dim bubble As New TrayItemBubbleWindow()
        bubble.Text = "Hello !"
        bubble.Title = String.Format("{0}", _cnt)
        bubble.HyperLink = "http://www.autodesk.com"
        bubble.HyperText = "Autodesk"
 
        _ti.ShowBubbleWindow(bubble)
    End Sub
 
    Private Sub MyForm_FormClosed( _
            ByVal sender As System.Object, _
            ByVal e As System.Windows.Forms.FormClosedEventArgs _
            ) Handles MyBase.FormClosed
        ' Stop the timer
        _myTimer.Stop()
        _myTimer.Dispose()
 
        ' Remove the tray item
        If _ti IsNot Nothing Then
            Dim sb As StatusBar = Application.StatusBar
            Dim tis As TrayItemCollection = sb.TrayItems
            tis.Remove(_ti)
            sb.Update()
        End If
    End Sub
End Class

Comments

3 responses to “Setting up a timer in a .NET sample that uses the AutoCAD .NET API”

  1. Why create an hidden form ? You can use a System.Windows.Form.Timer without a parent form?

  2. Thanks for pointing that out.
    Yes, I think that should also work correctly.

  3. Hi Balaji
    Can you list out the libraries for this code. It will be help full

Leave a Reply to yadwadCancel reply

Discover more from Autodesk Developer Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading