发布:2022/12/29 10:50:37作者:管理员 来源:本站 浏览次数:587
void PagePaint()
{
Console.WriteLine("Paint Start");
Paint();
Console.WriteLine("Paint End");
}
void Paint()
{
Rendering("Header");
Rendering(RequestBody());
Rendering("Footer");
}
string RequestBody()
{
Thread.Sleep(1000);
return "Body";
}
假设有这么个页面布局的方法,依次对头部、主体和底部进行渲染,头部和底部是固定的内容,而主体需要额外请求。
这里用Sleep模拟网络延时,Rendering方法其实也就是对Console.WriteLine的简单封装而已。。。
PagePaint运行过后,结果是这样的:
Paint Start
Header
Body
Footer
Paint End
挺正常的结果,但是Header渲染完以后页面就阻塞了,这个时候用户没法对Header进行操作。
于是就进行这样的修正:
async void Paint()
{
Rendering("Header");
Rendering(await RequestBody());
Rendering("Footer");
}
async Task<string> RequestBody()
{
return await Task.Run(() =>
{
Thread.Sleep(1000);
return "Body";
});
}
运行结果变成了这样:
Paint Start
Header
Paint End
Body
Footer
这样就能在Header出现之后不阻塞主线程了。
不过呢,Footer一直都得等到Body渲染完成后才能被渲染,这个逻辑现在看来还没问题,因为底部要相对于主体进行布局。
然而我这时候又想给页面加一个广告,而且是fixed定位的那种,管啥头部主体想盖住就盖住,你们在哪它不管。
比如这样写:
async void Paint()
{
Rendering(await RequestAds());
Rendering("Header");
Rendering(await RequestBody());
Rendering("Footer");
}
出现了很严重的问题,头部都得等广告加载好了才能渲染,这样显然是不对的。
所以应该改成这样:
async void Paint()
{
PaintAds();
Rendering("Header");
Rendering(await RequestBody());
Rendering("Footer");
}
async void PaintAds()
{
string ads = await Task.Run(() =>
{
Thread.Sleep(1000);
return "Ads";
});
Rendering(ads);
}
这样的运行结果就算令人满意了:
Paint Start
Header
Paint End
Ads
Body
Footer
总结:
1.Paint()加async表示是可异步的,当里面有awit的时候,调用Paint的线程会异步处理Paint()后面的代码
2.Paint()里面是同步的,想要实现异步效果,再嵌套个加async的异步方法.
总之async 不加awit就是异步,加了就同步处理
方法前面加个async,表明这个方法是多线程的,是异步的,主线程或调用该方法多线程不会等待方法结束,除非在调用的时候加awite等待..
实例测试:
private void button1_Click(object sender, EventArgs e)
{
textBox1.Text = "start\r\n";
aaa();//异步方法,如果里面有awits的时候启动异步,执行下一条代码=====>>"textBox1.Text += "dfgfdgdfdfg\r\n";"
textBox1.Text += "dfgfdgdfdfg\r\n";
}
public async void aaa()
{
List<Task<PP>> plist = new List<Task<PP>>();
for (int i = 0; i < 10; i++)
{
Task<PP> p = Getp(i);
// p.Start();
plist.Add(p);
//PP p = await Getp(i);
//textBox1.Text +=p.Name + "\r\n";
}
textBox1.Text += "11111111111111111111\r\n";
while (plist.Count>0)
{
try
{
Task<PP> imageTask = await Task.WhenAny(plist);
plist.Remove(imageTask);
PP pppppp = await imageTask;
textBox1.Text += pppppp.Name + "\r\n";
}
catch (Exception exc) { MessageBox.Show(exc.Message); }
}
textBox1.Text += "22222222222222222222\r\n";
}
public async Task<PP> Getp(int index)
{
PP p=new PP ();
switch (index)
{
case 1:
Thread.Sleep(1000);
p.Index=index;
p.Name=index.ToString();
return p;
case 2:
return await Task.Run(() =>
{
Thread.Sleep(100);
p.Index = index;
p.Name = index.ToString();
return p;
});
case 3:
return await Task.Run(() =>
{
Thread.Sleep(1000);
p.Index = index;
p.Name = index.ToString();
return p;
});
case 4:
return await Task.Run(() =>
{
Thread.Sleep(500);
p.Index = index;
p.Name = index.ToString();
return p;
});
default:
return await Task.Run(() =>
{
Thread.Sleep(2000);
p.Index = index;
p.Name = index.ToString();
return p;
});
}
}
© Copyright 2014 - 2024 柏港建站平台 ejk5.com. 渝ICP备16000791号-4