פתרון השאלה של handle¶
הקטע הבא הוא גוף פעולה בתוך wrapper שכבר מחזיק EventHandle. הוא מדגים את ההשאלה הידנית עבור API שמקבל מספר גולמי; עבור API שניתן להצהיר עם SafeHandle נעדיף את החתימה המנוהלת הישירה.
static void BorrowRaw(EventHandle handle, Action<nint> synchronousUse)
{
bool added = false;
try
{
handle.DangerousAddRef(ref added);
synchronousUse(handle.DangerousGetHandle());
}
finally
{
if (added) handle.DangerousRelease();
}
}
ה־Action חייב להיות סינכרוני ולא לשמור את המספר. אם הוא מתחיל פעולה שנמשכת אחרי החזרה, ה־finally משחרר מוקדם מדי. במקרה כזה בעלות ההשאלה עוברת לאובייקט פעולה שמשחרר אותה רק אחרי join או completion מוכח.
הדוגמה הבאה עצמאית ומראה context token שאינו מצביע לנתונים.
using System.Runtime.InteropServices;
var state = new State("request-7");
GCHandle root = GCHandle.Alloc(state);
try
{
nint token = GCHandle.ToIntPtr(root);
State recovered = (State)GCHandle.FromIntPtr(token).Target!;
Console.WriteLine(recovered.Id);
}
finally { root.Free(); }
sealed record State(string Id);
ה־WaitForSingleObject מחזיר WAIT_OBJECT_0 עבור event שסומן, WAIT_TIMEOUT עבור סיום ההמתנה בזמן ו־WAIT_FAILED עבור כשל שמאפשר לקרוא את last error. אין להחזיר bool שמאחד timeout וכשל. ההשאלה שנוצרה על ידי SafeHandle נשמרת עד חזרת הקריאה, אך אינה מחליפה סנכרון של מצב התוכן שה־event מסמן.