' by Daniel Moth (http://www.danielmoth.com/Blog/) Namespace System.Threading Public Class Semaphore Inherits WaitHandle Public Sub New(ByVal initialCount As Integer, ByVal maximumCount As Integer) Me.New(initialCount, maximumCount, Nothing) End Sub Public Sub New(ByVal initialCount As Integer, ByVal maximumCount As Integer, ByVal name As String) Me.New(initialCount, maximumCount, name, False) ' last param is dummy End Sub Public Sub New(ByVal initialCount As Integer, ByVal maximumCount As Integer, ByVal name As String, ByRef createdNew As Boolean) If (initialCount > maximumCount) OrElse (maximumCount < 1) OrElse (initialCount < 0) Then Throw New ArgumentException("RTFM please on what arguments are valid") End If Dim hwnd As IntPtr = Win32Api.CreateSemaphore(Nothing, initialCount, maximumCount, name) Dim er As Int32 If hwnd.ToInt32() = 0 Then er = System.Runtime.InteropServices.Marshal.GetLastWin32Error() Throw New ApplicationException("could not create semaphore " + er.ToString() + " " + name) End If If er = Win32Api.ERROR_ALREADY_EXISTS Then createdNew = False Else createdNew = True End If Me.Handle = hwnd End Sub Public Function Release() As Integer Return Me.Release(1) End Function Public Function Release(ByVal releaseCount As Integer) As Integer If (releaseCount < 1) Then Throw New ArgumentOutOfRangeException("releaseCount must be greater than 1, not " + releaseCount.ToString()) End If Dim ret As Integer If Win32Api.ReleaseSemaphore(Me.Handle, releaseCount, ret) = True Then Return ret End If Throw New ApplicationException("Semaphore full exception") End Function Public Overloads Overrides Function WaitOne() As Boolean Return WaitOne(-1, False) End Function Public Overloads Function WaitOne(ByVal millisecondsTimeout As Int32, ByVal notApplicableOnCE As Boolean) As Boolean Return (Win32Api.WaitForSingleObject(Me.Handle, millisecondsTimeout) <> Win32Api.WAIT_TIMEOUT) End Function Public Overloads Function WaitOne(ByVal aTs As TimeSpan, ByVal notApplicableOnCE As Boolean) As Boolean Return (Win32Api.WaitForSingleObject(Me.Handle, aTs.Milliseconds) <> Win32Api.WAIT_TIMEOUT) End Function Public Overrides Sub Close() GC.SuppressFinalize(Me) Win32Api.CloseHandle(Me.Handle) Me.Handle = New IntPtr(-1) End Sub Protected Overrides Sub Finalize() Win32Api.CloseHandle(Me.Handle) End Sub #Region "PInvokes" Private Class Win32Api Public Const WAIT_TIMEOUT As Int32 = &H102 '258 Public Const ERROR_ALREADY_EXISTS As Int32 = 183 _ Public Shared Function CreateSemaphore(ByVal lpSemaphoreAttributes As IntPtr, ByVal lInitialCount As Int32, ByVal lMaximumCount As Int32, ByVal lpName As String) As IntPtr End Function _ Public Shared Function ReleaseSemaphore(ByVal handle As IntPtr, ByVal lReleaseCount As Int32, ByRef previousCount As Int32) As Boolean End Function _ Friend Shared Function OpenSemaphore(ByVal desiredAccess As Integer, ByVal inheritHandle As Boolean, ByVal name As String) As IntPtr End Function _ Public Shared Function WaitForSingleObject(ByVal hHandle As IntPtr, ByVal dwMilliseconds As Int32) As Int32 End Function _ Public Shared Function CloseHandle(ByVal hObject As IntPtr) As Boolean End Function End Class #End Region End Class End Namespace