// 单击事件
private void btnClick_Click(object sender, EventArgs e)
{
this.btnClick.Enabled = false;
long length = AccessWeb();
this.btnClick.Enabled = true;
// 这里可以做一些不依赖回复的操作
OtherWork();
this.richTextBox1.Text += String.Format("\n 回复的字节长度为: {0}.\r\n", length);
txbMainThreadID.Text = Thread.CurrentThread.ManagedThreadId.ToString();
}
private long AccessWeb()
{
MemoryStream content = new MemoryStream();
// 对MSDN发起一个Web请求
HttpWebRequest webRequest = WebRequest.Create("http://msdn.microsoft.com/zh-cn/") as HttpWebRequest;
if (webRequest != null)
{
// 返回回复结果
using (WebResponse response = webRequest.GetResponse())
{
using (Stream responseStream = response.GetResponseStream())
{
responseStream.CopyTo(content);
}
}
}
txbAsynMethodID.Text = Thread.CurrentThread.ManagedThreadId.ToString();
return content.Length;
}
private void btnClick_Click(object sender, EventArgs e)
{
this.richTextBox1.Clear();
btnClick.Enabled = false;
AsyncMethodCaller caller = new AsyncMethodCaller(TestMethod);
IAsyncResult result = caller.BeginInvoke(GetResult, null);
//// 捕捉调用线程的同步上下文派生对象
//sc= SynchronizationContext.Current;
}
# region 使用APM实现异步编程
// 同步方法
private string TestMethod()
{
// 模拟做一些耗时的操作
// 实际项目中可能是读取一个大文件或者从远程服务器中获取数据等。
for (int i = 0; i < 10; i++)
{
Thread.Sleep(200);
}
return "点击我按钮事件完成";
}
// 回调方法
private void GetResult(IAsyncResult result)
{
AsyncMethodCaller caller = (AsyncMethodCaller)((AsyncResult)result).AsyncDelegate;
// 调用EndInvoke去等待异步调用完成并且获得返回值
// 如果异步调用尚未完成,则 EndInvoke 会一直阻止调用线程,直到异步调用完成
string resultvalue = caller.EndInvoke(result);
//sc.Post(ShowState,resultvalue);
richTextBox1.Invoke(showStateCallback, resultvalue);
}
// 显示结果到richTextBox
private void ShowState(object result)
{
richTextBox1.Text = result.ToString();
btnClick.Enabled = true;
}
// 显示结果到richTextBox
//private void ShowState(string result)
//{
// richTextBox1.Text = result;
// btnClick.Enabled = true;
//}
#endregion
private async void btnClick_Click(object sender, EventArgs e)
{
long length = await AccessWebAsync();
// 这里可以做一些不依赖回复的操作
OtherWork();
this.richTextBox1.Text += String.Format("\n 回复的字节长度为: {0}.\r\n", length);
txbMainThreadID.Text = Thread.CurrentThread.ManagedThreadId.ToString();
}
// 使用C# 5.0中提供的async 和await关键字来定义异步方法
// 从代码中可以看出C#5.0 中定义异步方法就像定义同步方法一样简单。
// 使用async 和await定义异步方法不会创建新线程,
// 它运行在现有线程上执行多个任务.
// 此时不知道大家有没有一个疑问的?在现有线程上(即UI线程上)运行一个耗时的操作时,
// 为什么不会堵塞UI线程的呢?
// 这个问题的答案就是 当编译器看到await关键字时,线程会
private async Task<long> AccessWebAsync()
{
MemoryStream content = new MemoryStream();
// 对MSDN发起一个Web请求
HttpWebRequest webRequest = WebRequest.Create("http://msdn.microsoft.com/zh-cn/") as HttpWebRequest;
if (webRequest != null)
{
// 返回回复结果
using (WebResponse response = await webRequest.GetResponseAsync())
{
using (Stream responseStream = response.GetResponseStream())
{
await responseStream.CopyToAsync(content);
}
}
}
txbAsynMethodID.Text = Thread.CurrentThread.ManagedThreadId.ToString() ;
return content.Length;
}
private void OtherWork()
{
this.richTextBox1.Text += "\r\n等待服务器回复中.................\n";
}
// 编译器为按钮Click事件生成的代码
private void btnClick_Click(object sender, EventArgs e)
{
<btnClick_Click>d__0 d__;
d__.<>4__this = this;
d__.sender = sender;
d__.e = e;
d__.<>t__builder = AsyncVoidMethodBuilder.Create();
d__.<>1__state = -1;
d__.<>t__builder.Start<<btnClick_Click>d__0>(ref d__);
}
// <btnClick_Click>d__0类型的定义,从下面代码可以看出它是一个结构体
// 该类型是编译器生成的一个嵌入类型
// 看到该类型的实现有没有让你联想到什么?
private struct <btnClick_Click>d__0 : IAsyncStateMachine
{
// Fields
public int <>1__state;
public Form1 <>4__this;
public AsyncVoidMethodBuilder <>t__builder;
private object <>t__stack;
private TaskAwaiter<long> <>u__$awaiter2;
public long <length>5__1;
public EventArgs e;
public object sender;
// Methods
private void MoveNext()
{
try
{
TaskAwaiter<long> CS$0$0001;
bool <>t__doFinallyBodies = true;
switch (this.<>1__state)
{
case -3:
goto Label_010E;
case 0:
break;
default:
// 获取用于等待Task(任务)的等待者。你要知道某个任务是否完成,我们就需要一个等待者对象对该任务进行一个监控,所以微软就定义了一个等待者对象的
// 从这里可以看出,其实async和await关键字背后的实现原理是基于任务的异步编程模式(TAP)
// 这里代码是在线程池线程上运行的
CS$0$0001 = this.<>4__this.AccessWebAsync().GetAwaiter();
// 如果任务完成就调转到Label_007A部分的代码
if (CS$0$0001.IsCompleted)
{
goto Label_007A;
}
// 设置状态为0为了退出回调方法。
this.<>1__state = 0;
this.<>u__$awaiter2 = CS$0$0001;
// 这个代码是做什么用的呢?让我们带着问题看下面的分析
this.<>t__builder.AwaitUnsafeOnCompleted<TaskAwaiter<long>, Form1.<btnClick_Click>d__0>(ref CS$0$0001, ref this);
<>t__doFinallyBodies = false;
// 返回到调用线程,即GUI线程,这也是该方法不会堵塞GUI线程的原因,不管任务是否完成都返回到GUI线程
return;
}
// 当任务完成时,不会执行下面的代码,会直接执行Label_007A中代码
CS$0$0001 = this.<>u__$awaiter2;
this.<>u__$awaiter2 = new TaskAwaiter<long>();
// 为了使再次回调MoveNext代码
this.<>1__state = -1;
Label_007A:
// 下面代码是在GUI线程上执行的
CS$0$0001 = new TaskAwaiter<long>();
long CS$0$0003 = CS$0$0001.GetResult();
this.<length>5__1 = CS$0$0003;
// 我们源码中的代码这里的
this.<>4__this.OtherWork();
this.<>4__this.richTextBox1.Text = this.<>4__this.richTextBox1.Text + string.Format("\n 回复的字节长度为: {0}.\r\n", this.<length>5__1);
this.<>4__this.txbMainThreadID.Text = Thread.CurrentThread.ManagedThreadId.ToString();
}
catch (Exception <>t__ex)
{
this.<>1__state = -2;
this.<>t__builder.SetException(<>t__ex);
return;
}
Label_010E:
this.<>1__state = -2;
this.<>t__builder.SetResult();
}
[DebuggerHidden]
private void SetStateMachine(IAsyncStateMachine param0)
{
this.<>t__builder.SetStateMachine(param0);
}
}
机械节能产品生产企业官网模板...
大气智能家居家具装修装饰类企业通用网站模板...
礼品公司网站模板
宽屏简约大气婚纱摄影影楼模板...
蓝白WAP手机综合医院类整站源码(独立后台)...苏ICP备2024110244号-2 苏公网安备32050702011978号 增值电信业务经营许可证编号:苏B2-20251499 | Copyright 2018 - 2025 源码网商城 (www.ymwmall.com) 版权所有