将同步代码包装成异步方法的最佳方法是什么?

本文关键字:最佳 方法 是什么 异步方法 同步 代码 包装 | 更新日期: 2023-09-27 18:07:14

我正在创建一个使用async-await方法的应用程序。但对我来说,使用它们有一个很大的问题。在阅读了几篇文章之后,我仍然不知道将繁重的同步操作包装到异步方法中的最佳方法是什么。

我有两个想法。哪一个是最好的?

1)当前实现。

private Task<List<UploadedTestModel>> ParseTestFiles(List<string> filesContent)
{
    var tcs = new TaskCompletionSource<List<UploadedTestModel>>();
    Task.Run(() =>
    {
        var resultList = new List<UploadedTestModel>();
        foreach (var testBody in filesContent)
        {
            try
            {
                var currentCulture = Thread.CurrentThread.CurrentCulture;
                var serializerSettings = new JsonSerializerSettings
                {
                    Culture = currentCulture
                };
                var parsedData = JsonConvert.DeserializeObject<UploadedTestModel>(testBody, serializerSettings);
                resultList.Add(parsedData);
            }
            catch(Exception exception)
            {
                tcs.SetException(exception);
            }
        }
        tcs.SetResult(resultList);
    });
    return tcs.Task;
}

我正在使用任务。Run和TaskCompletionSource

2)只使用Task。不运行TaskCompletionSource

private Task<List<UploadedTestModel>> ParseTestFiles(List<string> filesContent)
{
    return Task.Run(() =>
    {
       . . . .
       return resultList;          
    });
}

将同步代码包装成异步方法的最佳方法是什么?

我都不会使用。你将对任何调用你方法调用的人撒谎。当你公开一个异步操作时,调用者希望它是自然异步的,这意味着在它后面没有线程在工作。

你的所有方法本质上都是同步的,你应该这样公开它们。让调用者决定他是想同步调用它们还是使用线程并在那里排队,不要为它们做决定。

有一篇很棒的文章叫做我应该为同步方法公开异步包装器吗?Stephan Toub的书,书中讨论了不去做你想做的事情的所有理由。