Post Reply
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
|
Post Reply
|