1
using
System;
2
using
System.Threading ;
3
4
namespace
AsyncDemo
5
{
6
/**//**//**/
///
<summary>
7
///
如何异步调用 Visual C# 方法
8
///
出自:
http://support.microsoft.com/default.aspx?scid=kb%3Bzh-cn%3B315582
9
///
</summary>
10
class
AsyncDemo
11
{
12
/**//**//**/
///
<summary>
13
///
应用程序的主入口点。
14
///
</summary>
15
[STAThread]
16
static
void
Main(
string
[] args)
17
{
18
AsyncDemo ad
=
new
AsyncDemo () ;
19
//
ad.DemoSyncCall() ;
20
//
ad.DemoEndInvoke();
21
//
ad.DemoWaitHandle();
22
//
ad.DemoPolling();
23
ad.DemoCallback();
24
Console.WriteLine(
"
1111111111
"
);
25
Console.Read();
26
}
27
28
string
LongRunningMethod (
int
iCallTime,
out
int
iExecThread)
29
{
30
Thread.Sleep (iCallTime) ;
31
iExecThread
=
AppDomain.GetCurrentThreadId ();
32
return
"
MyCallTime was
"
+
iCallTime.ToString() ;
33
}
34
35
delegate
string
MethodDelegate(
int
iCallTime,
out
int
iExecThread) ;
36
37
/**//**//**//*
38
* 同步调用方法
39
*
*/
40
/**//**//**/
///
<summary>
41
///
示例 1: 同步调用方法
42
///
</summary>
43
public
void
DemoSyncCall()
44
{
45
string
s ;
46
int
iExecThread;
47
48
//
Create an instance of a delegate that wraps LongRunningMethod.
49
MethodDelegate dlgt
=
new
MethodDelegate (
this
.LongRunningMethod) ;
50
51
//
Call LongRunningMethod using the delegate.
52
s
=
dlgt(
3000
,
out
iExecThread);
53
54
Console.WriteLine(
string
.Format (
"
The delegate call returned the string: {0}, and the thread ID {1}
"
, s, iExecThread.ToString() ) );
55
56
}
57
58
/**//**//**//*
59
* 使用调用模式是要调用 BeginInvoke , 做某些处理主线程, 并调用 EndInvoke() 。
60
* 注意不 EndInvoke() 不返回直到异步调用已完成。
61
* 此调用模式是有用当要有调用线程正在执行异步调用, 同时工作。
62
* 有同时发生工作可改善许多应用程序的性能。
63
* 常见任务以异步运行以此方式是文件或网络操作。
64
*
*/
65
/**//**//**/
///
<summary>
66
///
示例 2: 通过 EndInvoke() 调用模式异步调用方法
67
///
</summary>
68
public
void
DemoEndInvoke()
69
{
70
MethodDelegate dlgt
=
new
MethodDelegate (
this
.LongRunningMethod) ;
71
string
s ;
72
int
iExecThread;
73
74
//
Initiate the asynchronous call.
75
IAsyncResult ar
=
dlgt.BeginInvoke(
3000
,
out
iExecThread,
null
,
null
);
76
77
//
Do some useful work here. This would be work you want to have
78
//
run at the same time as the asynchronous call.
79
80
//
Retrieve the results of the asynchronous call.
81
s
=
dlgt.EndInvoke (
out
iExecThread, ar) ;
82
83
Console.WriteLine(
string
.Format (
"
The delegate call returned the string: {0}, and the number {1}
"
, s, iExecThread.ToString() ) );
84
}
85
86
/**//**//**//*
87
* 由 BeginInvoke() 返回 IAsyncResult 具有一个 AsyncWaitHandle 属性。
88
* 该属性返回 WaitHandle 异步调用完成后, 通知是。 等待 WaitHandle 是常见线程同步技术。
89
* 通过是 WaitHandle WaitOne() 方法调用线程等待 WaitHandle 上。
90
* 直到是通知 WaitHandle WaitOne() 块。 当 WaitOne() 返回, 您在调用 EndInvoke() 之前进行一些额外工作。
91
* 对于执行文件或网络操作, 否则会阻塞调用主线程存为, 以前示例中此技术很有用。
92
*
*/
93
/**//**//**/
///
<summary>
94
///
示例 3: 异步调用方法并使用 A WaitHandle 来等待调用完成
95
///
</summary>
96
public
void
DemoWaitHandle ()
97
{
98
string
s ;
99
int
iExecThread;
100
101
MethodDelegate dlgt
=
new
MethodDelegate (
this
.LongRunningMethod) ;
102
103
//
Initiate the asynchronous call.
104
IAsyncResult ar
=
dlgt.BeginInvoke(
3000
,
out
iExecThread,
null
,
null
);
105
106
//
Do some useful work here. This would be work you want to have
107
//
run at the same time as the asynchronous call.
108
109
//
Wait for the WaitHandle to become signaled.
110
ar.AsyncWaitHandle.WaitOne() ;
111
112
//
Get the results of the asynchronous call.
113
s
=
dlgt.EndInvoke (
out
iExecThread, ar) ;
114
115
Console.WriteLine(
string
.Format (
"
The delegate call returned the string: {0}, and the number {1}
"
, s, iExecThread.ToString() ) );
116
}
117
118
/**//**//**//*
119
* 由 BeginInvoke() 返回 IAsyncResult 对象有个 IsCompleted 属性异步调用完成后返回 True 。
120
* 然后可调用 EndInvoke() 。 如果您应用程序不断工作对不做要长期函数调用已被此调用模式很有用。
121
* MicrosoftWindows 应用程序是这样的示例。
122
* 主线程的 Windows 应用程序可以继续以执行异步调用时处理用户输入。
123
* 它可定期检查 IsCompleted 到调用是否完成。 它调用 EndInvoke 当 IsCompleted 返回 True 。
124
* 直到它知道操作已完成因为 EndInvoke() 阻止直到异步操作为完整, 应用程序不调用它。
125
*
*/
126
/**//**//**/
///
<summary>
127
///
示例 4: 异步调用方法通过轮询调用模式
128
///
</summary>
129
public
void
DemoPolling()
130
{
131
MethodDelegate dlgt
=
new
MethodDelegate (
this
.LongRunningMethod) ;
132
string
s ;
133
int
iExecThread;
134
135
//
Initiate the asynchronous call.
136
IAsyncResult ar
=
dlgt.BeginInvoke(
3000
,
out
iExecThread,
null
,
null
);
137
138
//
Poll IAsyncResult.IsCompleted
139
while
(ar.IsCompleted
==
false
)
140
{
141
Thread.Sleep (
10
) ;
//
pretend to so some useful work
142
}
143
s
=
dlgt.EndInvoke (
out
iExecThread, ar) ;
144
145
Console.WriteLine(
string
.Format (
"
The delegate call returned the string: {0}, and the number {1}
"
, s, iExecThread.ToString() ) );
146
}
147
148
/**//**//**//*
149
* 本节, 中示例提供对 BeginInvoke() 函数, 异步调用完成后系统执行回调委托。
150
* 回调调用 EndInvoke() 并处理异步调用的结果。
151
* 如果启动异步调用线程不需要处理结果是调用此调用模式很有用。
152
* 异步调用完成后系统调用线程以外启动线程上调。
153
* 若使用此调用模式, 作为第二到最后 - BeginInvoke() 函数的参数必须传递 AsyncCallback 类型的委托。
154
* BeginInvoke() 还有最后参数键入 对象 到您可以将任何对象。 当它调用该对象可用于您回调函数。
155
* 为此参数一个重要用途是以传递用于初始化调用该委托。
156
* 回调函数然后使用与该委托 EndInvoke() 函数来完成调用。 此调用模式是所示。
157
*
*/
158
/**//**//**/
///
<summary>
159
///
示例 5: 异步方法完成后执行回调
160
///
</summary>
161
public
void
DemoCallback()
162
{
163
MethodDelegate dlgt
=
new
MethodDelegate (
this
.LongRunningMethod) ;
164
//
string s ;
165
int
iExecThread;
166
167
//
Create the callback delegate.
168
AsyncCallback cb
=
new
AsyncCallback(MyAsyncCallback);
169
170
//
Initiate the Asynchronous call passing in the callback delegate
171
//
and the delegate object used to initiate the call.
172
IAsyncResult ar
=
dlgt.BeginInvoke(
3000
,
out
iExecThread, cb,dlgt);
173
}
174
175
public
void
MyAsyncCallback(IAsyncResult ar)
176
{
177
string
s ;
178
int
iExecThread ;
179
180
//
Because you passed your original delegate in the asyncState parameter
181
//
of the Begin call, you can get it back here to complete the call.
182
MethodDelegate dlgt
=
(MethodDelegate) ar.AsyncState;
183
184
//
Complete the call.
185
s
=
dlgt.EndInvoke (
out
iExecThread, ar) ;
186
187
Console.WriteLine(
string
.Format (
"
The delegate call returned the string: {0}, and the number {1}
"
, s, iExecThread.ToString() ));
188
}
189
}
190
}