異步編程Task

儘可能使用異步編程(ASYNC-AWAIT)數據庫

 

異步編程模型是在C#5.0中引入的,並變得很是流行。ASP.NET Core使用相同的異步編程範例來使應用程序更可靠、更快和更穩定。編程

您應該在代碼中使用端到端異步編程。架構

讓咱們舉一個例子;咱們有一個ASP.NET CoreMVC應用程序,中間有一些數據庫的操做。正如咱們所知道的,它可能有不少分層結構,這都取決於用戶的項目架構,可是讓咱們舉一個簡單的例子,其中咱們有Controller》Repository 層等等。讓咱們看看如何在控制器層編寫示例代碼。異步

[HttpGet]
[Route("GetPosts")]
public async Task GetPosts()
{
try
{
var posts = await postRepository.GetPosts();
if (posts == null)
{
return NotFound();
}

return Ok(posts);
}
catch (Exception)
{
return BadRequest();

}
}

接下來的代碼然是了咱們如何在repository  層實現異步編程。async

public async Task<List<PostViewModel>> GetPosts()
{
if (db != null)
{
return await (from p in db.Post
from c in db.Category
where p.CategoryId == c.Id
select new PostViewModel
{
PostId = p.PostId,
Title = p.Title,
Description = p.Description,
CategoryId = p.CategoryId,
CategoryName = c.Name,
CreatedDate = p.CreatedDate
}).ToListAsync();
}

return null;
}

 

使用異步編程避免TASK.WAIT或TAST.RESULT異步編程

在使用異步編程時,我建議您避免使用Task.Wait和Task.Result並嘗試使用WAIT,緣由以下:post

  1. 它們阻塞線程直到任務完成,並等待任務完成。等待同步阻塞線程,直到任務完成。性能

  2. Wait 和 Task.Result 在AggregateException中包含全部類型的異常,並在在執行異常處理時增長複雜性。若是您使用的是等待await 而不是 Task.Wait和Task.Result的話,那麼您就沒必要擔憂異常的處理了。spa

  3. 有時,它們都會阻塞當前線程並建立死鎖。線程

  4. 只有在並行任務執行正在進行時才能使用Wait 和Task.Result 。咱們建議您不要在異步編程中使用它。

下面讓咱們分別演示下正確使用以及不建議使用Task.Wait 的例子,來加深理解吧!

// 正確的例子 
Task task = DoWork();
await task;

// 不建議使用的例子
Task task = DoWork();
task.Wait();

下面讓咱們分別演示下正確使用以及不規範使用Task.Result 的例子,來加深理解吧!

// Good Performance on UI 
Task<string> task = GetEmployeeName();
txtEmployeeName.Text = await task;

// Bad Performance on UI
Task<string> task = GetEmployeeName();
txtEmployeeName.Text = task.Result;

異步執行I/O操做

 

在執行I/O操做時,您應該異步執行它們,這樣就不會影響其餘進程。I/O操做意味着對文件執行一些操做,好比上傳或檢索文件。它能夠是任何操做如:圖像上傳,文件上傳或其餘任何操做。若是您試圖以同步的方式完成它,那麼它會阻塞主線程並中止其餘後臺執行,直到I/O完成爲止。所以,從提高性能上來講,您在對I/O進行操做時應該始終進行異步執行。

咱們有不少異步方法可用於I/O操做,如ReadAsync、WriteAsync、FlushAysnc等。下面是一個簡單的例子,說明咱們如何異步建立一個文件的副本。

public async void CreateCopyOfFile()
{
string dir = @"c:\Mukesh\files\";

using (StreamReader objStreamReader= File.OpenText(dir + "test.txt"))
{
using (StreamWriter objStreamWriter= File.CreateText(dir+ "copy_test.txt"))
{
await CopyFileToTarget(objStreamReader, objStreamWriter);
}
}
}

public async Task CopyFileToTarget(StreamReader objStreamReader, StreamWriter objStreamWriter)
{
int num;
char[] buffer = new char[0x1000];

while ((num= await objStreamReader.ReadAsync(buffer, 0, buffer.Length)) != 0)
{
await objStreamWriter.WriteAsync(buffer, 0, num); } }
相關文章
相關標籤/搜索