簡體   English   中英

C#任務調用同一實例

[英]C# Tasks Calling same instance

我對任務還很陌生,想在我的應用程序中實現它們。 我想要的是在頁面加載時在客戶端執行ajax請求,該函數調用我需要的所有目錄並將所有對象的JSON返回給客戶端。 我在服務器端創建的一項功能是執行多項任務。 因此,我對此有以下疑問:

  1. 加載該頁面所需的所有目錄並返回JSON對象是一種好習慣嗎?
  2. 如果任務調用一個類的相同實例,它實際上是否可以作為多線程工作? 還是在每個任務中創建實例更好?

      public JsonResult GetCatalogs() { JsonResult jSonResult = new JsonResult(); try { CatalogsRepository catalogsRepository = new CatalogsRepository(); Task<IList<CustomObject1>> task1 = Task.Factory.StartNew(() => { IList<CustomObject1> resultList1 = catalogsRepository.getFirstCatalog(); return resultList1; }); Task<IList<CustomObject2>> task2 = Task.Factory.StartNew(() => { IList<CustomObject2> resultList2 = catalogsRepository.getSecondCatalog(); return resultList2; }); Task<IList<CustomObject3>> task3 = Task.Factory.StartNew(() => { IList<CustomObject3> resultList3 = catalogsRepository.getThirdCatalog(); return resultList3; }); jSonResult = Json(new { result1 = task1.Result, learningMaterialTypeList = task2.Result, contentAssociatedList = task13.Result }); jSonResult.MaxJsonLength = int.MaxValue; jSonResult.JsonRequestBehavior = JsonRequestBehavior.AllowGet; } catch (Exception ex) { log.Error(ex); return Json(new Error { messageCode = 1, message = ex.Message }); } return jSonResult; } 
  3. 還是在每個任務中創建實例更好?

      public JsonResult GetCatalogs() { JsonResult jSonResult = new JsonResult(); try { Task<IList<CustomObject1>> task1 = Task.Factory.StartNew(() => { CatalogsRepository catalogsRepository = new CatalogsRepository(); IList<CustomObject1> resultList1 = catalogsRepository.getFirstCatalog(); return resultList1; }); Task<IList<CustomObject2>> task2 = Task.Factory.StartNew(() => { CatalogsRepository catalogsRepository = new CatalogsRepository(); IList<CustomObject2> resultList2 = catalogsRepository.getSecondCatalog(); return resultList2; }); Task<IList<CustomObject3>> task3 = Task.Factory.StartNew(() => { CatalogsRepository catalogsRepository = new CatalogsRepository(); IList<CustomObject3> resultList3 = catalogsRepository.getThirdCatalog(); return resultList3; }); jSonResult = Json(new { result1 = task1.Result, learningMaterialTypeList = task2.Result, contentAssociatedList = task13.Result }); jSonResult.MaxJsonLength = int.MaxValue; jSonResult.JsonRequestBehavior = JsonRequestBehavior.AllowGet; } catch (Exception ex) { log.Error(ex); return Json(new Error { messageCode = 1, message = ex.Message }); } return jSonResult; } 

我正在將MVC .NET 4.0與jQuery配合使用,在此先感謝您。

您的操作方法應該是異步的:

public async Task<JsonResult> GetCatalogs()

一旦您的方法是異步的,其他所有操作都將變得更加容易。 您可以取消那些Task.Run()調用,而只需正常調用這些方法(只要它們是異步的即可)並await它們。 將這些lambda變成單獨的異步方法(甚至C#7本地方法)可能是有道理的:

protected async Task<IList<CustomObject1>> GetResults1()
{
    CatalogsRepository catalogsRepository = new CatalogsRepository();
    var resultList1 = catalogsRepository.getFirstCatalog();
    return await resultList1.ToListAsync();
});

重要提示:要獲得結果,您應該使用await 切勿在異步ASP.NET環境中使用Result ,因為它將死鎖。

var jsonResult = Json(new
{
    result1 = await task1,
    learningMaterialTypeList = await task2,
    contentAssociatedList = await task3
});

至於您的問題:

加載該頁面所需的所有目錄並返回JSON對象是一種好習慣嗎?

沒有反對它的規則。 這是您要做出的設計決定。 優點是往返次數少,缺點是將所有這些東西都在公共接口中耦合在一起,使體系結構更加脆弱。

如果任務調用一個類的相同實例,它實際上是否可以作為多線程工作? 還是在每個任務中創建實例更好?

在真正的多線程中,通常最好在單獨的實例上工作,以便每個線程可以擁有自己的獨立內存緩存。 話雖這么說, 異步與多線程並不相同 ,實際上,在ASP.NET中,您可以確保不會同時執行兩個任務 (除非您做一些特殊的事情才能使它實現)。 相反,您一次只能獲得一個線程。 線程可能會更改,並且您的異步代碼將在等待點附近跳轉,但是根據設計,一次只能運行一段代碼。

1.我認為,通過返回JSON對象,您的意思是一個操作,該操作返回一個JsonObject並由客戶端的ajax調用。 您可以在應用程序的大多數地方執行此操作,但請記住,純MVC可能會失去很多好處。 第二件事是jQuery和Ajax難以維護,在復雜視圖的情況下,您將不得不編寫大量代碼,而這些代碼通常很難測試。 在asp.net MVC中,一個非常普遍的概念是通過GET方法返回ViewModels / Models,然后使用asp.net幫助器將數據從表單發送回控制器。 如果使用數據注釋屬性和jQuery非侵入式庫,則可以構建非常好的驗證,並且非常容易在后端和客戶端進行維護。 客戶端驗證將僅基於.net屬性免費生成,從而縮短了開發時間。 使用Ajax調用,您可以執行類似操作,但是代碼會更笨拙。

2和3。您的控制器應包含盡可能少的業務邏輯,所有邏輯應移至其他層,服務等。您的實際代碼過於復雜。

嘗試使用接口和IOC。 避免像現在在控制器中那樣創建對象的實例。 很難為此類編寫測試。 我認為這樣會更好:

private readonly ICatalogService _catalogService;

// Dependency injection thanks to Inversion of Control
public BlahController(ICatalogService catalogService){
     _catalogService=catalogService;
}

public async JsonResult GetCatalogs(params..){
     return await catalogService.getCatalogs(params..); //or catalogRepository
}

因此,您可以將所有業務邏輯從控制器中移到某個單獨的類。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM