50010702506256
分类:
.NET
我们使用异步编程可以自己开辟线程,也可以使用async,await关键字来实现
例如我们在主线程直接执行一个方法是会阻塞主线程的
static void Main(string[] args)
{
Console.WriteLine("主线程测试开始..");
Show();
Console.WriteLine("主线程测试结束..");
Console.ReadLine();
}
static void Show()
{
for (int i = 0; i < 5; i++)
{
Console.WriteLine("异步执行" + i.ToString() + "..");
Task.Delay(1000); //模拟耗时操作
}
}
输出完后,主线程才会执行
下面我们使用async,await来实现一个没有返回值的异步方法
没有返回值的异步方法很简单,写好了我们直接调用就好了
static void Main(string[] args)
{
Console.WriteLine("主线程测试开始..");
ShowAsync();
Console.WriteLine("主线程测试结束..");
Console.ReadLine();
}
static async void ShowAsync()
{
for (int i = 0; i < 5; i++)
{
Console.WriteLine("异步执行" + i.ToString() + "..");
await Task.Delay(1000); //模拟耗时操作
}
}效果如下,可以看到并没有阻塞主线程:

这里要注意Task.Delay返回的就是一个Task,所以前面可以使用await等待他

下面我们使用async,await来实现一个有返回值的异步方法
由于有返回值不想去影响主函数的方法,我们需要写一个方法来中转一下,在这个中转方法中去取到返回值
当然也可以把调用他的方法也修改为可以等待的异步方法,如果不想修改它就单独写一个方法吧
class Program
{
static void Main(string[] args)
{
Console.WriteLine("主线程测试开始..");
MethodAsync();
Console.WriteLine("主线程测试结束..");
Console.ReadLine();
}
/// <summary>
/// 获取返回值的中转方法
/// </summary>
static async void MethodAsync()
{
Console.WriteLine("开始异步代码");
int result = await ShowRAsync();
Console.WriteLine("异步代码执行完毕" + result);
}
static async Task<int> ShowRAsync()
{
for (int i = 0; i < 5; i++)
{
Console.WriteLine("异步执行" + i.ToString() + "..");
await Task.Delay(1000); //模拟耗时操作
}
return 200;
}
}效果如下:

tip:这里的ShowRAsync方法是返回的一个task,所以调用它的方法MethodAsync也可以使用await方法等待
相当于加了await就可以得到一个task的执行,但是那个方法必须申明async,那个方法就是一个异步方法
如果在方法当中不需要等待返回值,只是一个异步调用的话,就没有必要去使用async了,直接Task.Run去异步执行就好了
例如提供一个很简单的异步调用日志的方法
public static void AddLogAsync(string content, string type, string remark)
{
Task.Run(() =>
{
AddLog(content, type, remark);
});
}有返回值:
public Task<int> AddTNMessageAsync(TNMessage _message)
{
return Task.Run<int>(() =>
{
int count = EfHelper.Add(_message);
return count;
});
}查询数据库的时候的异步(ef 异步):
public Task<BlogSet> GetBlogSetByUIdAsync(int? _userid)
{
return context.BlogSet.Where(a => a.UserId == _userid).FirstOrDefaultAsync();
}微软官方的 一个例子:
public class PriorityListViewComponent : ViewComponent
{
private readonly ToDoContext db;
public PriorityListViewComponent(ToDoContext context)
{
db = context;
}
public async Task<IViewComponentResult> InvokeAsync(int maxPriority, bool isDone)
{
var items = await GetItemsAsync(maxPriority, isDone);
return View(items);
}
private Task<List<TodoItem>> GetItemsAsync(int maxPriority, bool isDone)
{
return db.ToDo.Where(x => x.IsDone == isDone && x.Priority <= maxPriority).ToListAsync();
}
}我的个人理解:
async,await其实里边就是开辟的线程,用这两个可以形成一种标准,一种规范,让人一看就知道是一个异步方法。也封装了很多,让我们方便使用。如果不需要返回值的话,直接调用。如果需要取到返回值就用另外一个包含async的去做一下中转,当然如果想把异步方法当同步使用也可以
另外他们一般都配合task使用
欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739。有需要软件开发,或者学习软件技术的朋友可以和我联系~(Q:815170684)