2017-08-02 65 views
1

感謝所有的回覆,我真的很感激它,並且學到了很多!我還了解到,我有很多東西要學習,並且會碰到書。我的任務並沒有等待完成

我仍然試圖得到等待和異步的掛鉤,所以我一直在搞亂,但我現在很難過。我做了大量的搜索,閱讀和研究,但我找不到問題。

所以我在做什麼是反序列化,並試圖返回一個對象

public static async Task<SomeObject> Deserialize(string filePath) 
    { 
     var task = Task.Factory.StartNew(() => LoadFile(filePath)); 

     await task; 

     return task.Result; 
    } 

上面的方法,然後在這裏稱爲:

public async Task DoStuff() 
    { 
     var load = await Helper.Deserialize(Helper.filePath); 

     try 
     { 
      Console.WriteLine(load.GetType()); 
     } 
     catch(Exception e) 
     { 
      Console.WriteLine(e); 
     } 
    } 

的代碼的其餘部分完成任務之前運行並且該對象總是以空值出現,使其無用。我知道自己做錯了什麼,但是在我花了幾個小時閱讀回答的問題和微軟文檔之後,我無法確定它是什麼。

@Fabio這裏是的LoadFile方法:

 private static SomeObject LoadFile(string path) 
    { 
     JsonSerializer json = new JsonSerializer(); 
     JsonTextReader reader = new JsonTextReader(new StreamReader(path)); 

     var obj = json.Deserialize(reader, typeof(SomeObject)); 
     reader.Close(); 

     return (SomeObject)obj; 
    } 
+1

嘗試刪除的await任務,而不是從反序列化FUNC返回任務。 – Hybridzz

+1

我建議使'LoadFile'' async'和'await'代替它調用的任何IO調用的'async'版本。你正在做的是真正意義上的CPU綁定任務https://blog.stephencleary.com/2013/11/taskrun-etiquette-examples-using.html – juharr

+0

你可以顯示'LoadFile'方法嗎? – Fabio

回答

1

您應該使用Task.Run代替Task.Factory.StartNew

public static Task<SomeObject> DeserializeAsync(string filePath) 
{ 
    return Task.Run(() => LoadFile(filePath)); 
} 

假設LoadFile回報SomeObject

或者你也可以重構LoadFile方法

private static Task<SomeObject> LoadFileAsync(string path) { 
    return Task.Run(() => { 
     JsonSerializer json = new JsonSerializer(); 
     using(var reader = new JsonTextReader(new StreamReader(path))) { 
      var obj = json.Deserialize(reader, typeof(SomeObject)); 
      return (SomeObject)obj; 
     } 
    });   
} 

public static async Task<SomeObject> DeserializeAsync(string filePath) 
{ 
    var obj = await LoadFileAsync(filePath); 
    return obj; 
} 
+0

好的,謝謝你的回覆,我現在正在嘗試。 – Acolytes

+0

非常感謝這篇文章。這解決了我的問題,我非常感謝你的時間。 – Acolytes

+1

即使使用'Task.Factory.StartNew..',OP的代碼示例也應該可以工作 - 但當然使用Task.Run是創建任務的正確方法。對不起,我不明白爲什麼在兩個任務中包裝代碼將解決問題。你可以解釋嗎? – Fabio

2

試試這個

public static Task<SomeObject> Deserialize(string filePath) 
    { 
     var task = Task.Run(() => LoadFile(filePath)); 

     return task;  
    }