-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Expand file tree
/
Copy pathControl.ThreadMethodEntry.cs
More file actions
90 lines (78 loc) · 2.69 KB
/
Copy pathControl.ThreadMethodEntry.cs
File metadata and controls
90 lines (78 loc) · 2.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
namespace System.Windows.Forms;
public partial class Control
{
/// <summary>
/// Used with BeginInvoke/EndInvoke
/// </summary>
private class ThreadMethodEntry : IAsyncResult
{
internal Control _caller;
internal Control _marshaler;
internal Delegate? _method;
internal object?[]? _args;
internal object? _retVal;
internal Exception? _exception;
internal bool _synchronous;
private ManualResetEvent? _resetEvent;
private readonly Lock _invokeSyncObject = new();
// Store the execution context associated with the caller thread, and
// information about which thread actually got the stack applied to it.
internal ExecutionContext? _executionContext;
// Optionally store the synchronization context associated with the callee thread.
// This overrides the sync context in the execution context of the caller thread.
internal SynchronizationContext? _syncContext;
internal ThreadMethodEntry(
Control caller,
Control marshaler,
Delegate? method,
object?[]? args,
bool synchronous,
ExecutionContext? executionContext)
{
_caller = caller;
_marshaler = marshaler;
_method = method;
_args = args;
_synchronous = synchronous;
_executionContext = executionContext;
}
public object? AsyncState => null;
public WaitHandle AsyncWaitHandle
{
get
{
if (_resetEvent is null)
{
lock (_invokeSyncObject)
{
_resetEvent ??= new ManualResetEvent(false);
if (IsCompleted)
{
_resetEvent.Set();
}
}
}
return _resetEvent;
}
}
public bool CompletedSynchronously => IsCompleted && _synchronous;
public bool IsCompleted { get; private set; }
internal void Complete()
{
lock (_invokeSyncObject)
{
IsCompleted = true;
try
{
_resetEvent?.Set();
}
catch (ObjectDisposedException)
{
// AsyncWaitHandle exposes the event and allows callers to dispose it before completion.
}
}
}
}
}