2014-06-12 112 views
1

所以我只是想讓我的服務層asyncASP NET MVC 5任務異步創建一個異步方法

我有一個新的服務ProjectManagement,我希望它的GetProjects方法是異步的。

public Task<string> GetProjectsAsync() 
{ 
    var json = JsonConvert.SerializeObject(_repository.All<Projects>()); 

    return json; 
} 

我知道這個方法行不通,顯然是因爲我返回一個字符串,而不是一個Task<string>。那麼如何使用Task.Run()來運行此方法並返回結果呢?

我看過這個documentation,我對如何使用它有點困惑?

所有我希望能夠在我的控制器做的是:

var jsonData = await _projectManagement.GetProjectsAsync(); 
+2

使方法異步的唯一真正原因是如果你可以異步執行IO。如果你不能,你可以把它作爲同步方法。 – Servy

+0

當你有返回類型的方法「任務」時返回一個字符串是正確的行爲。只需在你的'GetProjectsAsync()'方法之前放置async即可。 – Abhijeet

+3

@Abhijeet這是一個可怕的想法。這是創建一個同步的方法,只是將其結果包裝在一個任務中,實質上是聲明它是異步的謊言。你不應該那樣做。如果你不想讓這個方法異步,你不應該對你的調用者撒謊,並聲稱你是異步的。 – Servy

回答

5

當轉換爲async,你要開始「並且朝着你的控制器/ UI工作。我做了很多轉換,這是我找到的最好的方法。

因此,首先確定任何自然異步的操作;任何I/O約束是一個很好的選擇。你已經確定了一個:數據庫調用。

接下來,從最底層代碼開始,並使其成爲異步。這是你的問題進入的地方;你正在考慮通過使用Task.Run在中間強制異步,但是你需要深入到更低的層次,並使其始終保持異步。

例如,我會假設你的資料庫是使用實體框架和你All<T>方法看起來是這樣的:

public List<T> All<T>() 
{ 
    return _context.Set<T>().ToList(); 
} 

然後你就開始做這個倉庫方法的異步版本:

public Task<List<T>> AllAsync<T>() 
{ 
    return _context.Set<T>().ToListAsync(); 
} 

一旦你有了到位的至少一個異步存儲庫的方法,你就可以開始改變你的服務層是異步的,所以這段代碼:

public string GetProjects() 
{ 
    var json = JsonConvert.SerializeObject(_repository.All<Projects>()); 
    return json; 
} 

變成這樣:

public async Task<string> GetProjectsAsync() 
{ 
    var json = JsonConvert.SerializeObject(await _repository.AllAsync<Projects>()); 
    return json; 
} 

一旦服務層是異步的,那麼你就可以改變你的控制器是異步的。

+0

我不能實現'AllAsync'方法,因爲它說「不能隱式地將列表轉換爲任務」 –

+0

再看看代碼。它是'ToListAsync',而不是'ToList'。 –

+0

是的,我做到了:) –

-3

你應該嘗試在「葉此鏈接http://www.dotnetperls.com/async

private async void DoAsyncWork() 
{ 
    var data = await GetProjectAsync(); 
} 

async Task<string> GetProjectAsynce() 
{ 
    // code to get stuff done 
    // await key word may be needed depending on 
    // what you are doinf 
    return JsonConvert.SerializeObject(myRepository.All<Projects>()); 
    // convert to string first of course 
}