Post Reply

Forums -> UltraMon™ SDK -> Multi-threading problem
Steve Teoh   2004-10-21 01:02
I am facing a problem with multithreading on VB.NET to display files such as excel viewer etc on multiple monitors.

The display is very erratic and sometimes the windows are displayed all on monitor 1.

Would appreciate if you can shed some light on this. Thank you very much.

Below is the excerpt of the code

Public Function ShowScreen(Optional ByVal index As Integer = 0) As Boolean
Dim i As Integer
Dim th(GetTopMonitors()) As Thread
Try
AddHandler ThreadCompleted, AddressOf TaskCompleted
ParentThread = Thread.CurrentThread

'remove previous sessions
RemoveAllApps()

'save icon positions and settings
sys.SavePositions(POS_ALL)

'disable secondary display
sys.SecondaryDisable()

For i = 0 To index - 1
CurrentMonitor = i + 1
If filename <> "" Then
th(i) = New Thread(AddressOf ThreadProcedure)
th(i).Name = System.Diagnostics.Process.GetCurrentProcess.Id
th(i).IsBackground = False
th(i).Priority = ThreadPriority.Normal
th(i).Start()
runningThreads += 1
End If
Next

'enable display
sys.SecondaryEnable()

Catch ex As Exception
MsgBox(ex.Message & vbCrLf & ex.StackTrace, MsgBoxStyle.Critical, ex.Source)
End Try
End Function

Public Sub ThreadProcedure()
Try
Dim dir As String = LCase(System.Environment.GetEnvironmentVariable("WINDIR"))
If filename = "" Then
Console.WriteLine("thread: " & Thread.CurrentThread.Name & " does not have filename!")
Exit Sub
End If
PostToMonitor(filename, CurrentMonitor)
Catch ex As Exception
MsgBox(ex.Message & vbCrLf & ex.StackTrace, MsgBoxStyle.Critical, ex.Source)
End Try
End Sub


Public Function PostToMonitor(ByVal appname As String, ByVal monitor As Integer) As Boolean
Dim procid As Integer
Try
inddisp = CreateObject("UltraMon.IndDisp") 'independent display
procid = inddisp.DetachedApps.LaunchAndAdd(appname, monitor)
wnd = CreateObject("UltraMon.Window")
If wnd.GetAppMainWindow(procid, 0) = True Then
wnd.Monitor = monitor
wnd.Title = "MONITOR - " & monitor
wnd.SHOWSTATE = SHOWSTATE_MAXIMIZED
wnd.ApplyChanges(0)
RaiseEvent ThreadCompleted(wnd.Title)
Return True
End If
Catch ex As Exception
MsgBox(ex.Message & vbCrLf & ex.StackTrace, MsgBoxStyle.Critical, ex.Source)
Return False
End Try
End Function

Sincerely,
Steve Teoh
Technology Powerhouse (M) Sdn Bhd, Malaysia
Christian Studer   2004-10-21 07:58
A couple of potential issues I noticed:

- you are disabling the secondary monitors right before launching the applications. This way, when the threads start, the secondary monitors might still be disabled, so moving the application won't work

- I guess CurrentMonitor and filename are global variables? In this case, there seems to be a problem with the way the thread procedure uses CurrentMonitor: by the time the thread actually uses CurrentMonitor, the variable might already have been incremented again

- the IndDisp object should only be used when you want to use virtual independent displays. If you just want to launch an application, use the UltraMon.Utility object's Run method instead

- when calling GetAppMainWindow, you should specify a non-zero timeout value, for example 20000 (= 20 seconds), so that the application has time to start up and create its windows

Christian Studer - www.realtimesoft.com
Steve Teoh   2004-10-21 19:52
Hi Christian,

The variables are safe with the variable. The value displayed while debugging in console showed that it is correct.

'For multithreading
dim filename As String
dim CurrentMon As Integer

'console output
Thread:1 starting ..\sample\Microsoft Excel Worksheet 1.xls at 22/10/2004 15:40:07 .....
Thread:1 process id:3936 monitor:1 changes applied ..\sample\Microsoft Excel Worksheet 1.xls at 22/10/2004 15:40:42 .....
MONITOR - 1 completed

thread:2 monitor:2 file = ..\sample\Microsoft Excel Worksheet 2.xls
Thread:2 starting ..\sample\Microsoft Excel Worksheet 2.xls at 22/10/2004 15:40:42 .....
Thread:2 process id:1448 monitor:2 changes applied ..\sample\Microsoft Excel Worksheet 2.xls at 22/10/2004 15:40:55 .....
MONITOR - 2 completed

You are right about the disabling of secondary display and the timeout issue. I have experimented with several values and it seems that this value may vary from 10sec up to more than 60sec depending on the applications.

There is still unexpected result because the spawned thread that I use to launch the independent display may return before the call to UltramonWindowClass object ends. This will leave the window in an incomplete state. E.g. Only the Excel program is started whereas the excel file is not loaded. Sometimes, the files are loaded, but the window title is not updated to reflect the recent change.

It seems to me that I will have to revert back to the one display at a time formula to make it work.

Once again, thank you very much for your prompt response.

Sincerely,
Steve Teoh
Technology Powerhouse (M) Sdn Bhd, Malaysia
Steve Teoh   2004-10-21 19:56
Sorry.

The ThreadStatic() construct does not show up correctly in the page.

\" dim filename As String\"

Sincerely,
Steve Teoh
Technology Powerhouse (M) Sdn Bhd, Malaysia
Forums -> UltraMon™ SDK -> Multi-threading problem

Post Reply