Skip to content

Commit b2eafc8

Browse files
authored
Merge pull request #415 from Eta0/eta/synchronization
Fix a few synchronization-related crashes
2 parents 8287f6b + 46578e7 commit b2eafc8

File tree

2 files changed

+68
-35
lines changed

2 files changed

+68
-35
lines changed

CompactGUI/Application.xaml.vb

Lines changed: 55 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -7,32 +7,47 @@ Class Application
77

88
Public Shared ReadOnly mutex As New Mutex(False, "Global\CompactGUI")
99

10+
Private pipeServerCancellation As New CancellationTokenSource()
11+
Private pipeServerTask As Task
12+
1013
Private mainWindow As MainWindow
1114

1215
Private Async Sub Application_Startup(sender As Object, e As StartupEventArgs)
1316

1417
SettingsHandler.InitialiseSettings()
1518

19+
Dim acquiredMutex As Boolean
20+
21+
Try
22+
acquiredMutex = mutex.WaitOne(0, False)
23+
Catch ex As AbandonedMutexException
24+
' This means the mutex was acquired successfully,
25+
' but its last owner exited abruptly, without releasing it.
26+
' acquiredMutex should still be True here, but further error checking
27+
' on shared program state could be added here as well.
28+
acquiredMutex = True
29+
End Try
1630

17-
If Not SettingsHandler.AppSettings.AllowMultiInstance AndAlso Not mutex.WaitOne(0, False) Then
31+
If Not SettingsHandler.AppSettings.AllowMultiInstance AndAlso Not acquiredMutex Then
1832

1933
If e.Args.Length <> 0 AndAlso e.Args(0) = "-tray" Then
2034
MessageBox.Show("An instance of CompactGUI is already running")
2135
Application.Current.Shutdown()
2236

2337
End If
2438

25-
Using client = New NamedPipeClientStream("CompactGUI")
39+
Using client = New NamedPipeClientStream(".", "CompactGUI", PipeDirection.Out)
2640
client.Connect()
2741
Using writer = New StreamWriter(client)
28-
writer.WriteLine(e.Args(0))
42+
If e.Args.Length > 0 Then
43+
writer.WriteLine(e.Args(0))
44+
End If
2945
End Using
3046
End Using
3147

3248
Application.Current.Shutdown()
3349
ElseIf Not SettingsHandler.AppSettings.AllowMultiInstance Then
34-
35-
ProcessNextInstanceMessage()
50+
pipeServerTask = ProcessNextInstanceMessage()
3651
End If
3752

3853

@@ -56,31 +71,40 @@ Class Application
5671
' can be handled in this file.
5772

5873

59-
Private Async Sub ProcessNextInstanceMessage()
60-
61-
Await Task.Run(Sub()
62-
While True
63-
64-
Using server = New NamedPipeServerStream("CompactGUI")
65-
server.WaitForConnection()
66-
Using reader = New StreamReader(server)
67-
Dim message = reader.ReadLine()
68-
mainWindow.Dispatcher.Invoke(Sub()
69-
mainWindow.Show()
70-
mainWindow.WindowState = WindowState.Normal
71-
mainWindow.Topmost = True
72-
mainWindow.Activate()
73-
mainWindow.Topmost = False
74-
If message IsNot Nothing Then
75-
mainWindow.ViewModel.SelectFolder(message)
76-
77-
End If
78-
End Sub)
79-
80-
End Using
81-
End Using
82-
End While
83-
End Sub)
84-
End Sub
74+
Private Async Function ProcessNextInstanceMessage() As Task
75+
Using server = New NamedPipeServerStream("CompactGUI",
76+
PipeDirection.In,
77+
1,
78+
PipeTransmissionMode.Byte,
79+
PipeOptions.Asynchronous)
80+
While Not pipeServerCancellation.IsCancellationRequested
81+
Try
82+
Await server.WaitForConnectionAsync(pipeServerCancellation.Token)
83+
Catch ex As OperationCanceledException
84+
Return
85+
End Try
86+
Using reader = New StreamReader(server)
87+
Dim message = Await reader.ReadLineAsync()
88+
mainWindow.Dispatcher.Invoke(Sub()
89+
mainWindow.Show()
90+
mainWindow.WindowState = WindowState.Normal
91+
mainWindow.Topmost = True
92+
mainWindow.Activate()
93+
mainWindow.Topmost = False
94+
If message IsNot Nothing Then
95+
mainWindow.ViewModel.SelectFolder(message)
96+
End If
97+
End Sub)
98+
End Using
99+
End While
100+
End Using
101+
End Function
102+
103+
Public Async Function ShutdownPipeServer() As Task
104+
If pipeServerTask IsNot Nothing Then
105+
pipeServerCancellation.Cancel()
106+
Await pipeServerTask
107+
End If
108+
End Function
85109

86110
End Class

CompactGUI/ViewModels/MainViewModel.vb

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -258,10 +258,19 @@ Public Class MainViewModel : Inherits ObservableObject
258258
.Arguments = $"""{ActiveFolder.FolderName}""",
259259
.Verb = "runas"}
260260
}
261-
Application.mutex.Dispose()
262-
myproc.Start()
263-
Application.Current.Shutdown()
264-
261+
Dim app As Application = Application.Current
262+
app.ShutdownPipeServer().ContinueWith(
263+
Sub()
264+
app.Dispatcher.Invoke(
265+
Sub()
266+
Application.mutex.ReleaseMutex()
267+
Application.mutex.Dispose()
268+
End Sub
269+
)
270+
myproc.Start()
271+
app.Dispatcher.Invoke(Sub() app.Shutdown())
272+
End Sub
273+
)
265274
End Sub
266275

267276

0 commit comments

Comments
 (0)