-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathNonBlockingWait.cs
More file actions
92 lines (77 loc) · 3.05 KB
/
NonBlockingWait.cs
File metadata and controls
92 lines (77 loc) · 3.05 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
91
// *** Example: Waiting for event without blocking UI in .NET 3.5 WinForms ***
// https://github.com/MSDN-WhiteKnight/CodeSamples
using System;
using System.IO;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Reflection;
using System.Runtime.InteropServices;
namespace WindowsFormsTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
[DllImport("user32.dll")]
static extern int MsgWaitForMultipleObjectsEx(uint nCount, IntPtr[] pHandles,
uint dwMilliseconds, uint dwWakeMask, uint dwFlags);
const uint QS_ALLEVENTS = 1215;
const int WAIT_OBJECT_0 = 0;
const int WAIT_FAILED = -1;
const uint INFINITE = 0xFFFFFFFF;
public static void AwaitEvent(object o, string evt)
{
if (o == null || evt == null) throw new ArgumentNullException("Arguments cannot be null");
EventInfo einfo = o.GetType().GetEvent(evt);
if (einfo == null)
{
throw new ArgumentException(String.Format("*{0}* has no *{1}* event", o, evt));
}
ManualResetEvent wh = new ManualResetEvent(false);
MethodInfo mi = null;
Delegate deleg = null;
EventHandler handler = null;
//код обработчика события
handler = (s, e) =>
{
mi = handler.Method;
deleg = Delegate.CreateDelegate(einfo.EventHandlerType, handler.Target, mi);
einfo.RemoveEventHandler(s, deleg); //отцепляем обработчик события
wh.Set();
};
mi = handler.Method;
deleg = Delegate.CreateDelegate(einfo.EventHandlerType, handler.Target, mi); //получаем делегат нужного типа
einfo.AddEventHandler(o, deleg); //присоединяем обработчик события
var swh = wh.SafeWaitHandle;
using (swh)
{
IntPtr h = swh.DangerousGetHandle();
while (true)
{
int res = MsgWaitForMultipleObjectsEx(1, new IntPtr[] { h }, INFINITE, QS_ALLEVENTS, 0);
switch (res)
{
case WAIT_OBJECT_0:
return;
case WAIT_OBJECT_0 + 1:
Application.DoEvents();
break;
default:
throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());
}
}
}
}
private void button1_Click(object sender, EventArgs e)
{
Form2 f = new Form2();
f.Show();
AwaitEvent(f, "FormClosed");
MessageBox.Show("Finished!");
}
}
}