What is the best way for wrapping synchronous code

2020-02-10 05:21发布

问题:

I am creating an application with using async-await methods. But There is a large problem for me with using them. After reading few articles I still don't know what is the best way for wrapping my heavy sync operations to async methods.

I have 2 ideas. Which one is the best?

1) Current realization.

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;
}

I'm using Task.Run and TaskCompletionSource

2) Using only Task.Run without TaskCompletionSource

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

回答1:

I would use neither. You'll be lying to whoever invokes your method call. When you expose an async operation, the callers expect it to be naturally asynchronous, meaning there is no thread behind it doing work.

All your methods are inherintly synchronous, and you should expose them as so. Leave it up to the caller to decide if he wants to invoke them synchronously or use a thread and queue it there, don't decide for them.

There is great article called Should I expose asynchronous wrappers for synchronous methods? by Stephan Toub which talks about all the reasons not to do what you're trying to do. I suggest reading it.