将同步代码包装到异步方法中的最佳方法是什么
What is the best way for wrapping synchronous code into asynchronous method
我正在使用异步等待方法创建应用程序。但是使用它们对我来说是个大问题。阅读了几篇文章后,我仍然不知道将繁重的同步操作包装到异步方法的最佳方法是什么。
我有两个想法。哪一个最好?
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;
}
我正在使用 Task.Run 和 TaskCompletionSource
2) 只使用 Task.Run 而没有 TaskCompletionSource
private Task<List<UploadedTestModel>> ParseTestFiles(List<string> filesContent)
{
return Task.Run(() =>
{
. . . .
return resultList;
});
}
我都不会用。无论谁调用您的方法调用,您都会撒谎。当您公开一个异步操作时,调用者期望它自然是异步的,这意味着它背后没有线程在工作。
你所有的方法都是天生同步的,你应该这样公开它们。让调用者决定他是想同步调用它们还是使用线程并在那里排队,不要为他们决定。
Stephan Toub 发表了一篇名为 Should I expose asynchronous wrappers for synchronous methods? 的精彩文章,其中讨论了不做您想做的事情的所有原因。我建议阅读它。
我正在使用异步等待方法创建应用程序。但是使用它们对我来说是个大问题。阅读了几篇文章后,我仍然不知道将繁重的同步操作包装到异步方法的最佳方法是什么。
我有两个想法。哪一个最好?
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;
}
我正在使用 Task.Run 和 TaskCompletionSource
2) 只使用 Task.Run 而没有 TaskCompletionSource
private Task<List<UploadedTestModel>> ParseTestFiles(List<string> filesContent)
{
return Task.Run(() =>
{
. . . .
return resultList;
});
}
我都不会用。无论谁调用您的方法调用,您都会撒谎。当您公开一个异步操作时,调用者期望它自然是异步的,这意味着它背后没有线程在工作。
你所有的方法都是天生同步的,你应该这样公开它们。让调用者决定他是想同步调用它们还是使用线程并在那里排队,不要为他们决定。
Stephan Toub 发表了一篇名为 Should I expose asynchronous wrappers for synchronous methods? 的精彩文章,其中讨论了不做您想做的事情的所有原因。我建议阅读它。