§ ITPOW >> 文档 >> C#

多线程与异步-Task.Run、await、async 以异步方式执行

作者:vkvi 来源:ITPOW(原创) 日期:2017-2-19

本文适用于 .NET Framework 4.5 及以上版本。低版本中无此特性。

Task.run

传统的防止大量工作阻塞 UI,用的是线程。现在 C# 发展越来越强大,有很多种方法了,虽然略有不同,但归根到底还是线程。

由 Task 来处理,一是代码更简洁,二是底层交给 .NET,.NET 分配会更合理。

private void button1_Click(object sender, EventArgs e)
{
	SetValue();
}

private void SetValue()
{
	Task.Run(() => {
		Thread.Sleep(2000); // 模拟大量工作阻塞 2 秒
		button1.Text = "1";
	});
}

如上代码,在点击按钮后,是可以拖动窗口界面的,说明并没有影响 UI。

() => 是 Lambda 表达式,跟 delegate ()一个道理。

以上还没有涉及到返回值,如果要有返回值,就要引入 await、async。

private void button1_Click(object sender, EventArgs e)
{
	SetValue();
}

private async void SetValue()
{
	button1.Text = await GetValue();
}

private Task<string> GetValue()
{
	return Task.Run(() =>
	{
		Thread.Sleep(2000); // 模拟大量工作阻塞 2 秒
		return "1";
	});
}

关于返回值,实际这里有两个层面:

  • 一是函数的返回值:

    • void 表示函数无返回值。

    • Task 表示函数返回值是 Task,但是异步无返回值。

  • 二是这个异步的返回值。

    • Task 表示函数返回值是 Task,但是异步无返回值。

    • Task<T> 表示函数返回值是 Task<T>,异步返回值是 T。

其实上面是讲了两个知识点:一是 Task,二是 asyncawait

  • 如果有返回值,就要在返回类型上加上 Task<>,比如:Task<string>。

  • 如果不要返回值,就直接是 Task GetValue()。

  • 由于内部有 await,就必须用 async 标记。

更详细的,请参见:到底是 return await Task.Run 还是 return Task.Run?

相关阅读

相关文章