异步反序列化调用在 C# 中不起作用

Async Deserialization call not working in C#

我正在使用 Newtonsoft.Json 读取 json 文件。我正在尝试对 json 文件进行 aysnc 调用以读取其数据,但不幸的是它没有返回任何内容。我在没有异步的情况下尝试过并且它完美运行,以下是我的代码:

public static async Task<T> LoadAsync<T>(string filePath)
{
        // filePath: any json file present locally on the disk
        string basePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase).Replace("file:\", "");
        string fullPath = Path.Combine(basePath, filePath);
        using (var stream = File.OpenRead(fullPath))
        {
            var reader = new StreamReader(stream, Encoding.GetEncoding("iso-8859-1"));
            var task = Task.Factory.StartNew(() => JsonConvert.DeserializeObject<T>(reader.ReadToEnd()));
            var value = await task;
            return value;
        }
}

我尝试调试,但调试器没有在上述方法中运行 "return value",我通过以下函数调用上述方法:

private void GetDataFromJson()
{
        var value = JsonUtilities.LoadAsync<TaxOffice>(Constant.TAXJSONINPUTFILE);
}

可能是什么问题?文件存在于我的本地计算机上。

I am trying to make a aysnc call to the json file to read its data

你真的要异步制作代码吗? JsonUtilities class 是否提供 LoadAsync() 方法的同步版本?

你的方法是同步的:

private void GetDataFromJson()
{
        var value = JsonUtilities.LoadAsync<TaxOffice>(Constant.TAXJSONINPUTFILE);
}

它只做一件事:调用 LoadAsync()。它确实将该方法的 return 值存储在 value 中,但您永远不会使用 value。所以它被忽略了。 LoadAsync() 的 return 值不是 TaxOffice 对象。它是一个 Task,代表 LoadAsync() 正在做的工作。在该任务完成之前,无法获得价值。但是 GetDataFromJson() 不会等待任务完成。因此,如果调用者希望它在方法 returns 之前完成,它将非常失望。

如何最好地修复您的代码尚不清楚,因为您没有提供 a good, minimal, complete code example 显示您需要帮助的内容。但是您可以遵循两个明显的策略:

使方法异步:

private async Task GetDataFromJson()
{
        var value = await JsonUtilities.LoadAsync<TaxOffice>(Constant.TAXJSONINPUTFILE);

        // presumably you do something with "value" here?
}

这是最好的方法。但它会要求调用者能够正确处理异步调用。它也可能需要变成 async 方法。和它的来电者。依此类推,直到到达调用堆栈的顶部(例如事件处理程序方法)。

在整个调用堆栈中切换到 async 有点麻烦,但如果您这样做,代码会工作得更好。您的线程(可能是 UI 线程)不会因等待操作而卡住,您也将准备好正确处理其他异步操作。

忽略LoadAsync()方法的异步性质:

private void GetDataFromJson()
{
        var value = JsonUtilities.LoadAsync<TaxOffice>(Constant.TAXJSONINPUTFILE).Result;

        // presumably you do something with "value" here?
}

这是 Not Very Good™ 方法。有用。但它会占用您当前的线程,直到异步操作完成,从而抵消了异步操作的全部好处。