AbandonedMutexException 類別
定義
重要
部分資訊涉及發行前產品,在發行之前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。
當一個執行緒取得另一個執行緒已放棄,但是結束時並未釋放的 Mutex 物件時,所擲回的例外狀況。
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
- 繼承
- 繼承
- 屬性
範例
下列程式碼範例會執行放棄五個 Mutex 的執行緒,示範其對 、 WaitAny 和 WaitAll 方法的影響 WaitOne 。 屬性的值 MutexIndex 會針對 WaitAny 呼叫顯示。
注意
對 方法的 WaitAny 呼叫會由其中一個已放棄的 Mutex 中斷。 另一個已放棄的 mutex 仍 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.
備註
當執行緒放棄 Mutex 時,會在取得 mutex 的下一個執行緒中擲回例外狀況。 執行緒可能會取得 mutex,因為其已經在等候 Mutex,或因為稍後進入 mutex。
放棄的 Mutex 表示嚴重的程式設計錯誤。 當執行緒結束而不釋放 Mutex 時,受 mutex 保護的資料結構可能不是一致的狀態。 在 2.0 版.NET Framework之前,這類問題很難探索,因為當放棄的 Mutex 導致等候完成時,不會擲回任何例外狀況。 如需詳細資訊,請參閱 Mutex 類別。
要求 Mutex 擁有權的下一個執行緒可以處理此例外狀況並繼續,前提是可以驗證資料結構的完整性。
建構函式
AbandonedMutexException() |
使用預設值,初始化 AbandonedMutexException 類別的新執行個體。 |
AbandonedMutexException(Int32, WaitHandle) |
使用已放棄 Mutex 的指定索引 (若適用的話) 以及表示此 Mutex 的 AbandonedMutexException 物件,初始化 Mutex 類別的新執行個體 。 |
AbandonedMutexException(SerializationInfo, StreamingContext) |
使用序列化資料,初始化 AbandonedMutexException 類別的新執行個體。 |
AbandonedMutexException(String) |
使用指定的錯誤訊息,初始化 AbandonedMutexException 類別的新執行個體。 |
AbandonedMutexException(String, Exception) |
使用指定的錯誤訊息和內部例外狀況初始化 AbandonedMutexException 類別的新執行個體。 |
AbandonedMutexException(String, Exception, Int32, WaitHandle) |
使用指定的錯誤訊息、內部例外狀況、已放棄 Mutex 的索引 (若適用的話),以及表示此 Mutex 的 AbandonedMutexException 物件,初始化 Mutex 類別的新執行個體。 |
AbandonedMutexException(String, Int32, WaitHandle) |
以指定的錯誤訊息、已放棄 Mutex 的索引 (若適用的話) 以及放棄的 Mutex 初始化 AbandonedMutexException 類別的新執行個體。 |
屬性
Data |
取得鍵值組的集合,這些鍵值組會提供關於例外狀況的其他使用者定義資訊。 (繼承來源 Exception) |
HelpLink |
取得或設定與這個例外狀況相關聯的說明檔連結。 (繼承來源 Exception) |
HResult |
取得或設定 HRESULT,它是指派給特定例外狀況的編碼數值。 (繼承來源 Exception) |
InnerException |
取得造成目前例外狀況的 Exception 執行個體。 (繼承來源 Exception) |
Message |
取得描述目前例外狀況的訊息。 (繼承來源 Exception) |
Mutex |
取得造成例外狀況的已放棄 Mutex (若為已知)。 |
MutexIndex |
取得造成例外狀況之已放棄 Mutex 的索引 (若為已知)。 |
Source |
取得或設定造成錯誤的應用程式或物件的名稱。 (繼承來源 Exception) |
StackTrace |
取得呼叫堆疊上即時運算框架的字串表示。 (繼承來源 Exception) |
TargetSite |
取得擲回目前例外狀況的方法。 (繼承來源 Exception) |
方法
Equals(Object) |
判斷指定的物件是否等於目前的物件。 (繼承來源 Object) |
GetBaseException() |
在衍生類別中覆寫時,傳回一或多個後續的例外狀況的根本原因 Exception。 (繼承來源 Exception) |
GetHashCode() |
做為預設雜湊函式。 (繼承來源 Object) |
GetObjectData(SerializationInfo, StreamingContext) |
在衍生類別中覆寫時,使用例外狀況的資訊設定 SerializationInfo。 (繼承來源 Exception) |
GetType() |
取得目前執行個體的執行階段類型。 (繼承來源 Exception) |
MemberwiseClone() |
建立目前 Object 的淺層複製。 (繼承來源 Object) |
ToString() |
建立並傳回目前例外狀況的字串表示。 (繼承來源 Exception) |
事件
SerializeObjectState |
已過時。
當例外狀況序列化,以建立包含例外狀況相關序列化資料的例外狀況狀態物件時,就會發生此事件。 (繼承來源 Exception) |