AbandonedMutexException.MutexIndex Свойство
Определение
Важно!
Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
Получает индекс брошенного мьютекса, вызвавшего исключение (если он известен).
public:
property int MutexIndex { int get(); };
public int MutexIndex { get; }
member this.MutexIndex : int
Public ReadOnly Property MutexIndex As Integer
Значение свойства
Индекс в массиве дескрипторов ожидания, переданных Mutex методуWaitAny, объекта, представляющего заброшенный мьютекс, или -1, если индекс брошенного мьютекса не удалось определить.
Примеры
В следующем примере кода выполняется поток, который отменяет пять мьютексов. Заброшенные мьютексы используются для демонстрации влияния на WaitHandle.WaitOneвызовы методов , WaitAnyи WaitAll . Для вызова отображается WaitAny значение MutexIndex свойства .
Примечание
Вызов прерывается WaitAny одним из заброшенных мьютексов. Другой заброшенный мьютекс может по-прежнему вызывать AbandonedMutexException исключение последующими методами ожидания.
using namespace System;
using namespace System::Threading;
namespace SystemThreadingExample
{
public ref class Example
{
private:
static ManualResetEvent^ dummyEvent =
gcnew ManualResetEvent(false);
static Mutex^ orphanMutex1 = gcnew Mutex;
static Mutex^ orphanMutex2 = gcnew Mutex;
static Mutex^ orphanMutex3 = gcnew Mutex;
static Mutex^ orphanMutex4 = gcnew Mutex;
static Mutex^ orphanMutex5 = gcnew Mutex;
public:
static void ProduceAbandonMutexException(void)
{
// Start a thread that grabs all five mutexes, and then
// abandons them.
Thread^ abandonThread =
gcnew Thread(gcnew ThreadStart(AbandonMutex));
abandonThread->Start();
// Make sure the thread is finished.
abandonThread->Join();
// Wait on one of the abandoned mutexes. The WaitOne
// throws an AbandonedMutexException.
try
{
orphanMutex1->WaitOne();
Console::WriteLine("WaitOne succeeded.");
}
catch (AbandonedMutexException^ ex)
{
Console::WriteLine("Exception in WaitOne: {0}",
ex->Message);
}
finally
{
// Whether or not the exception was thrown,
// the current thread owns the mutex, and
// must release it.
orphanMutex1->ReleaseMutex();
}
// Create an array of wait handles, consisting of one
// ManualResetEvent and two mutexes, using two more of
// the abandoned mutexes.
array <WaitHandle^>^ waitFor = {dummyEvent,
orphanMutex2, orphanMutex3};
// WaitAny returns when any of the wait handles in the
// array is signaled. Either of the two abandoned mutexes
// satisfy the wait, but lower of the two index values is
// returned by MutexIndex. Note that the Try block and
// the Catch block obtain the index in different ways.
try
{
int index = WaitHandle::WaitAny(waitFor);
Console::WriteLine("WaitAny succeeded.");
(safe_cast<Mutex^>(waitFor[index]))->ReleaseMutex();
}
catch (AbandonedMutexException^ ex)
{
Console::WriteLine("Exception in WaitAny at index {0}"
"\r\n\tMessage: {1}", ex->MutexIndex,
ex->Message);
(safe_cast<Mutex^>(waitFor[ex->MutexIndex]))->
ReleaseMutex();
}
orphanMutex3->ReleaseMutex();
// Use two more of the abandoned mutexes for the WaitAll
// call. WaitAll doesn't return until all wait handles
// are signaled, so the ManualResetEvent must be signaled
// by calling Set().
dummyEvent->Set();
waitFor[1] = orphanMutex4;
waitFor[2] = orphanMutex5;
// Because WaitAll requires all the wait handles to be
// signaled, both mutexes must be released even if the
// exception is thrown. Thus, the ReleaseMutex calls are
// placed in the Finally block. Again, MutexIndex returns
// the lower of the two index values for the abandoned
// mutexes.
//
try
{
WaitHandle::WaitAll(waitFor);
Console::WriteLine("WaitAll succeeded.");
}
catch (AbandonedMutexException^ ex)
{
Console::WriteLine("Exception in WaitAny at index {0}"
"\r\n\tMessage: {1}", ex->MutexIndex,
ex->Message);
}
finally
{
orphanMutex4->ReleaseMutex();
orphanMutex5->ReleaseMutex();
}
}
private:
[MTAThread]
static void AbandonMutex()
{
orphanMutex1->WaitOne();
orphanMutex2->WaitOne();
orphanMutex3->WaitOne();
orphanMutex4->WaitOne();
orphanMutex5->WaitOne();
Console::WriteLine(
"Thread exits without releasing the mutexes.");
}
};
}
//Entry point of example application
[MTAThread]
int main(void)
{
SystemThreadingExample::Example::ProduceAbandonMutexException();
}
// This code example produces the following output:
// Thread exits without releasing the mutexes.
// Exception in WaitOne: The wait completed due to an abandoned mutex.
// Exception in WaitAny at index 1
// Message: The wait completed due to an abandoned mutex.
// Exception in WaitAll at index -1
// Message: The wait completed due to an abandoned mutex.
using System;
using System.Threading;
public class Example
{
private static ManualResetEvent _dummy = new ManualResetEvent(false);
private static Mutex _orphan1 = new Mutex();
private static Mutex _orphan2 = new Mutex();
private static Mutex _orphan3 = new Mutex();
private static Mutex _orphan4 = new Mutex();
private static Mutex _orphan5 = new Mutex();
[MTAThread]
public static void Main()
{
// Start a thread that takes all five mutexes, and then
// ends without releasing them.
//
Thread t = new Thread(new ThreadStart(AbandonMutex));
t.Start();
// Make sure the thread is finished.
t.Join();
// Wait on one of the abandoned mutexes. The WaitOne returns
// immediately, because its wait condition is satisfied by
// the abandoned mutex, but on return it throws
// AbandonedMutexException.
try
{
_orphan1.WaitOne();
Console.WriteLine("WaitOne succeeded.");
}
catch(AbandonedMutexException ex)
{
Console.WriteLine("Exception on return from WaitOne." +
"\r\n\tMessage: {0}", ex.Message);
}
finally
{
// Whether or not the exception was thrown, the current
// thread owns the mutex, and must release it.
//
_orphan1.ReleaseMutex();
}
// Create an array of wait handles, consisting of one
// ManualResetEvent and two mutexes, using two more of the
// abandoned mutexes.
WaitHandle[] waitFor = {_dummy, _orphan2, _orphan3};
// WaitAny returns when any of the wait handles in the
// array is signaled, so either of the two abandoned mutexes
// satisfy its wait condition. On returning from the wait,
// WaitAny throws AbandonedMutexException. The MutexIndex
// property returns the lower of the two index values for
// the abandoned mutexes. Note that the Try block and the
// Catch block obtain the index in different ways.
//
try
{
int index = WaitHandle.WaitAny(waitFor);
Console.WriteLine("WaitAny succeeded.");
// The current thread owns the mutex, and must release
// it.
Mutex m = waitFor[index] as Mutex;
if (m != null) m.ReleaseMutex();
}
catch(AbandonedMutexException ex)
{
Console.WriteLine("Exception on return from WaitAny at index {0}." +
"\r\n\tMessage: {1}", ex.MutexIndex, ex.Message);
// Whether or not the exception was thrown, the current
// thread owns the mutex, and must release it.
//
if (ex.Mutex != null) ex.Mutex.ReleaseMutex();
}
// Use two more of the abandoned mutexes for the WaitAll call.
// WaitAll doesn't return until all wait handles are signaled,
// so the ManualResetEvent must be signaled by calling Set().
_dummy.Set();
waitFor[1] = _orphan4;
waitFor[2] = _orphan5;
// The signaled event and the two abandoned mutexes satisfy
// the wait condition for WaitAll, but on return it throws
// AbandonedMutexException. For WaitAll, the MutexIndex
// property is always -1 and the Mutex property is always
// null.
//
try
{
WaitHandle.WaitAll(waitFor);
Console.WriteLine("WaitAll succeeded.");
}
catch(AbandonedMutexException ex)
{
Console.WriteLine("Exception on return from WaitAll. MutexIndex = {0}." +
"\r\n\tMessage: {1}", ex.MutexIndex, ex.Message);
}
finally
{
// Whether or not the exception was thrown, the current
// thread owns the mutexes, and must release them.
//
_orphan4.ReleaseMutex();
_orphan5.ReleaseMutex();
}
}
[MTAThread]
public static void AbandonMutex()
{
_orphan1.WaitOne();
_orphan2.WaitOne();
_orphan3.WaitOne();
_orphan4.WaitOne();
_orphan5.WaitOne();
// Abandon the mutexes by exiting without releasing them.
Console.WriteLine("Thread exits without releasing the mutexes.");
}
}
/* This code example produces the following output:
Thread exits without releasing the mutexes.
Exception on return from WaitOne.
Message: The wait completed due to an abandoned mutex.
Exception on return from WaitAny at index 1.
Message: The wait completed due to an abandoned mutex.
Exception on return from WaitAll. MutexIndex = -1.
Message: The wait completed due to an abandoned mutex.
*/
Option Explicit
Imports System.Threading
Public Class Example
Private Shared _dummy As New ManualResetEvent(False)
Private Shared _orphan1 As New Mutex()
Private Shared _orphan2 As New Mutex()
Private Shared _orphan3 As New Mutex()
Private Shared _orphan4 As New Mutex()
Private Shared _orphan5 As New Mutex()
<MTAThread> _
Public Shared Sub Main()
' Start a thread that takes all five mutexes, and then
' ends without releasing them.
'
Dim t As New Thread(AddressOf AbandonMutex)
t.Start()
' Make sure the thread is finished.
t.Join()
' Wait on one of the abandoned mutexes. The WaitOne returns
' immediately, because its wait condition is satisfied by
' the abandoned mutex, but on return it throws
' AbandonedMutexException.
Try
_orphan1.WaitOne()
Console.WriteLine("WaitOne succeeded.")
Catch ex As AbandonedMutexException
Console.WriteLine("Exception on return from WaitOne." _
& vbCrLf & vbTab & "Message: " _
& ex.Message)
Finally
' Whether or not the exception was thrown, the current
' thread owns the mutex, and must release it.
'
_orphan1.ReleaseMutex()
End Try
' Create an array of wait handles, consisting of one
' ManualResetEvent and two mutexes, using two more of the
' abandoned mutexes.
Dim waitFor(2) As WaitHandle
waitFor(0) = _dummy
waitFor(1) = _orphan2
waitFor(2) = _orphan3
' WaitAny returns when any of the wait handles in the
' array is signaled, so either of the two abandoned mutexes
' satisfy its wait condition. On returning from the wait,
' WaitAny throws AbandonedMutexException. The MutexIndex
' property returns the lower of the two index values for
' the abandoned mutexes. Note that the Try block and the
' Catch block obtain the index in different ways.
'
Try
Dim index As Integer = WaitHandle.WaitAny(waitFor)
Console.WriteLine("WaitAny succeeded.")
Dim m As Mutex = TryCast(waitFor(index), Mutex)
' The current thread owns the mutex, and must release
' it.
If m IsNot Nothing Then m.ReleaseMutex()
Catch ex As AbandonedMutexException
Console.WriteLine("Exception on return from WaitAny at index " _
& ex.MutexIndex & "." _
& vbCrLf & vbTab & "Message: " _
& ex.Message)
' Whether or not the exception was thrown, the current
' thread owns the mutex, and must release it.
'
If ex.Mutex IsNot Nothing Then ex.Mutex.ReleaseMutex()
End Try
' Use two more of the abandoned mutexes for the WaitAll call.
' WaitAll doesn't return until all wait handles are signaled,
' so the ManualResetEvent must be signaled by calling Set().
_dummy.Set()
waitFor(1) = _orphan4
waitFor(2) = _orphan5
' The signaled event and the two abandoned mutexes satisfy
' the wait condition for WaitAll, but on return it throws
' AbandonedMutexException. For WaitAll, the MutexIndex
' property is always -1 and the Mutex property is always
' Nothing.
'
Try
WaitHandle.WaitAll(waitFor)
Console.WriteLine("WaitAll succeeded.")
Catch ex As AbandonedMutexException
Console.WriteLine("Exception on return from WaitAll. MutexIndex = " _
& ex.MutexIndex & "." _
& vbCrLf & vbTab & "Message: " _
& ex.Message)
Finally
' Whether or not the exception was thrown, the current
' thread owns the mutexes, and must release them.
'
CType(waitFor(1), Mutex).ReleaseMutex()
CType(waitFor(2), Mutex).ReleaseMutex()
End Try
End Sub
<MTAThread> _
Public Shared Sub AbandonMutex()
_orphan1.WaitOne()
_orphan2.WaitOne()
_orphan3.WaitOne()
_orphan4.WaitOne()
_orphan5.WaitOne()
' Abandon the mutexes by exiting without releasing them.
Console.WriteLine("Thread exits without releasing the mutexes.")
End Sub
End Class
' This code example produces the following output:
'
'Thread exits without releasing the mutexes.
'Exception on return from WaitOne.
' Message: The wait completed due to an abandoned mutex.
'Exception on return from WaitAny at index 1.
' Message: The wait completed due to an abandoned mutex.
'Exception on return from WaitAll. MutexIndex = -1.
' Message: The wait completed due to an abandoned mutex.
Комментарии
Если исключение возникает при вызове WaitHandle.WaitAny метода , это свойство возвращает индекс брошенного мьютекса с наименьшим индексом в массиве объектов, переданных WaitHandleWaitAnyв , или -1, если не удалось определить заброшенный мьютекс. Если исключение возникает при вызове WaitOne или WaitAll, это свойство всегда возвращает значение -1.