2017-08-02 70 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;  
    }