AbandonedMutexException Klasa
Definicja
Ważne
Niektóre informacje odnoszą się do produktu w wersji wstępnej, który może zostać znacząco zmodyfikowany przed wydaniem. Firma Microsoft nie udziela żadnych gwarancji, jawnych lub domniemanych, w odniesieniu do informacji podanych w tym miejscu.
Wyjątek zgłaszany, gdy jeden wątek uzyskuje Mutex obiekt porzucony przez inny wątek, zamykając go bez zwalniania.
public ref class AbandonedMutexException : Exception
public ref class AbandonedMutexException : SystemException
public class AbandonedMutexException : Exception
public class AbandonedMutexException : SystemException
[System.Runtime.InteropServices.ComVisible(false)]
[System.Serializable]
public class AbandonedMutexException : SystemException
type AbandonedMutexException = class
inherit Exception
type AbandonedMutexException = class
inherit SystemException
[<System.Runtime.InteropServices.ComVisible(false)>]
[<System.Serializable>]
type AbandonedMutexException = class
inherit SystemException
Public Class AbandonedMutexException
Inherits Exception
Public Class AbandonedMutexException
Inherits SystemException
- Dziedziczenie
- Dziedziczenie
- Atrybuty
Przykłady
Poniższy przykład kodu wykonuje wątek, który porzuca pięć muteksów, demonstrując ich wpływ na WaitOnemetody , WaitAnyi WaitAll . Wartość MutexIndex właściwości jest wyświetlana dla wywołania WaitAny .
Uwaga
Wywołanie WaitAny metody jest przerywane przez jedną z porzuconych muteksów. Inne porzucone mutex może nadal spowodować, że zostanie AbandonedMutexException zgłoszony przez kolejne metody oczekiwania.
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.
Uwagi
Gdy wątek porzuca mutex, wyjątek jest zgłaszany w następnym wątku, który uzyskuje mutex. Wątek może uzyskać mutex, ponieważ już czekał na mutex lub ponieważ wchodzi w mutex w późniejszym czasie.
Porzucony mutex wskazuje poważny błąd programowania. Gdy wątek kończy się bez zwalniania mutexu, struktury danych chronione przez mutex mogą nie być w stanie spójnym. Przed wersją 2.0 .NET Framework takie problemy były trudne do odnalezienia, ponieważ nie zgłoszono wyjątku, jeśli oczekiwanie zostało zakończone w wyniku porzuconego mutexu. Aby uzyskać więcej informacji, zobacz klasę Mutex .
Następny wątek żądania własności mutex może obsłużyć ten wyjątek i kontynuować, pod warunkiem, że można zweryfikować integralność struktur danych.
Konstruktory
AbandonedMutexException() |
Inicjuje nowe wystąpienie klasy AbandonedMutexException z domyślnymi wartościami. |
AbandonedMutexException(Int32, WaitHandle) |
Inicjuje nowe wystąpienie AbandonedMutexException klasy z określonym indeksem porzuconego mutexu, jeśli ma to zastosowanie, oraz Mutex obiekt reprezentujący mutex. |
AbandonedMutexException(SerializationInfo, StreamingContext) |
Inicjuje nowe wystąpienie klasy AbandonedMutexException z zserializowanymi danymi. |
AbandonedMutexException(String) |
Inicjuje AbandonedMutexException nowe wystąpienie klasy z określonym komunikatem o błędzie. |
AbandonedMutexException(String, Exception) |
Inicjuje AbandonedMutexException nowe wystąpienie klasy z określonym komunikatem o błędzie i wyjątkiem wewnętrznym. |
AbandonedMutexException(String, Exception, Int32, WaitHandle) |
Inicjuje nowe wystąpienie AbandonedMutexException klasy z określonym komunikatem o błędzie, wyjątkiem wewnętrznym, indeksem porzuconego mutexu, jeśli ma to zastosowanie, oraz obiektem reprezentującym Mutex mutex. |
AbandonedMutexException(String, Int32, WaitHandle) |
Inicjuje nowe wystąpienie AbandonedMutexException klasy z określonym komunikatem o błędzie, indeks porzuconego mutexu, jeśli ma to zastosowanie, i porzuconym mutexem. |
Właściwości
Data |
Pobiera kolekcję par klucz/wartość, które zapewniają dodatkowe informacje zdefiniowane przez użytkownika dotyczące wyjątku. (Odziedziczone po Exception) |
HelpLink |
Pobiera lub ustawia link do pliku pomocy skojarzonego z tym wyjątkiem. (Odziedziczone po Exception) |
HResult |
Pobiera lub ustawia HRESULT, zakodowaną wartość liczbową przypisaną do określonego wyjątku. (Odziedziczone po Exception) |
InnerException |
Exception Pobiera wystąpienie, które spowodowało bieżący wyjątek. (Odziedziczone po Exception) |
Message |
Pobiera komunikat opisujący bieżący wyjątek. (Odziedziczone po Exception) |
Mutex |
Pobiera porzucony mutex, który spowodował wyjątek, jeśli jest znany. |
MutexIndex |
Pobiera indeks porzuconego mutexu, który spowodował wyjątek, jeśli jest znany. |
Source |
Pobiera lub ustawia nazwę aplikacji lub obiektu, który powoduje błąd. (Odziedziczone po Exception) |
StackTrace |
Pobiera reprezentację ciągu natychmiastowych ramek w stosie wywołań. (Odziedziczone po Exception) |
TargetSite |
Pobiera metodę, która zgłasza bieżący wyjątek. (Odziedziczone po Exception) |
Metody
Equals(Object) |
Określa, czy dany obiekt jest taki sam, jak bieżący obiekt. (Odziedziczone po Object) |
GetBaseException() |
Po przesłonięciu w klasie pochodnej funkcja zwraca Exception główną przyczynę co najmniej jednego kolejnego wyjątku. (Odziedziczone po Exception) |
GetHashCode() |
Służy jako domyślna funkcja skrótu. (Odziedziczone po Object) |
GetObjectData(SerializationInfo, StreamingContext) |
Po zastąpieniu w klasie pochodnej ustawia SerializationInfo element z informacjami o wyjątku. (Odziedziczone po Exception) |
GetType() |
Pobiera typ środowiska uruchomieniowego bieżącego wystąpienia. (Odziedziczone po Exception) |
MemberwiseClone() |
Tworzy płytkią kopię bieżącego Objectelementu . (Odziedziczone po Object) |
ToString() |
Tworzy i zwraca reprezentację ciągu bieżącego wyjątku. (Odziedziczone po Exception) |
Zdarzenia
SerializeObjectState |
Nieaktualne.
Występuje, gdy wyjątek jest serializowany w celu utworzenia obiektu stanu wyjątku zawierającego serializowane dane o wyjątku. (Odziedziczone po Exception) |