二重起動メモ

たまには

VB.NETのことも書くよ!

アプリをシリアライズ化したい

同じアプリを起動したときに
最初のプロセスが終わるまで次のプロセスが待機するというプログラム書いた
System.Threading.Mutexを使ってます。

Public Shared Function Main(ByVal Args() As String) As Integer
  Dim objMutex As Mutex = New Mutex(False, Application.ProductName)
  Do While (objMutex.WaitOne(1000, False) = False)
  Loop
  
  'ここに処理を書く
  
End Function

ただし

これだと処理の最中にobjMutexがGCに襲われて二重で起動ができちゃったりする
ビルドがDebugの場合だとGC起きても*1開放されないけど
Releaseだった場合、あっさりと開放されちゃう
開発しているときは大丈夫でも、お客さんにリリースした後に不具合がでるという感じだ

GC対策

Public Shared Function Main(ByVal Args() As String) As Integer
  Dim objMutex As Mutex = New Mutex(False, Application.ProductName)
  Do While (objMutex.WaitOne(1000, False) = False)
  Loop
  
  'ここに処理を書く
  
  GC.KeepAlive(objMutex)
End Function

GCに襲われないためには参照されればいい
GC::KeepAlive(:Object)っていうのがただ単に参照するだけのメソッドで、これを使えば安心
MutexをNewしてからGC.KeepAliveが呼ばれるまでの間、インスタンスが保障される

これでもいいかも

Public Shared Function Main(ByVal Args() As String) As Integer
  Dim objMutex As Mutex = New Mutex(False, Application.ProductName)
  Do While (objMutex.WaitOne(1000, False) = False)
  Loop
  
  'ここに処理を書く
  
  objMutex.ReleaseMutex()
  objMutex.Close()
End Function

いや、むしろこっちの方がいいかも



2009-10-07 理解が誤っていたので追記です
ミューテックスの理解が誤っていた

*1:そもそもGCが起きない?