Скажем, у меня есть сотни классов, которые реализуют общий интерфейс с методом «вычислить». Некоторые классы будут выполнять асинхронно (например, читать файл), а другие классы, реализующие тот же интерфейс, будут выполнять синхронный код (например, складывать два числа). Какой хороший способ закодировать это, для обслуживания и для производительности?
Сообщения, которые я читал до сих пор, всегда рекомендуют делать методы async/await всплывающими для вызывающих. Итак, если у вас есть одна операция, которая является асинхронной, сделайте вызывающую программу асинхронной, затем вызывающую ее асинхронной и так далее. Так что это заставляет меня думать, что интерфейс должен быть асинхронным. Однако это создает проблему при реализации интерфейса с синхронным кодом.
Одна идея, о которой я подумал, состоит в том, чтобы предоставить в интерфейсе 2 метода, один асинхронный и один синхронный, и одно логическое свойство, чтобы сообщить вызывающей стороне, какой метод вызывать. Хотя это выглядело бы очень некрасиво.
В настоящее время у меня есть только один метод интерфейса, который является асинхронным. Затем для синхронных реализаций они заключают код в объект Task:
using System.IO;
using System.Threading.Tasks;
namespace TestApp
{
interface IBlackBox
{
Task<string> PullText();
}
sealed class MyAsyncBlackBox : IBlackBox
{
public async Task<string> PullText()
{
using (var reader = File.OpenText("Words.txt"))
{
return await reader.ReadToEndAsync();
}
}
}
sealed class MyCachedBlackBox : IBlackBox
{
public Task<string> PullText()
{
return Task.Run(() => "hello world");
}
}
}
Является ли это правильным подходом к созданию и реализации интерфейса, который лишь иногда является асинхронным? У меня есть много классов, которые реализуют короткие синхронные операции, и я беспокоюсь, что это может добавить много накладных расходов. Есть ли какой-то другой способ сделать это, который мне не хватает?
Task.Run(...)
, используйтеTask.FromResult(...);
. Ваша библиотека не должна использоватьTask.Run(...)
, потому что это будет использовать новый поток (вроде как, это сложнее), а не просто работать в текущем выполняющемся потоке. - person Nelson   schedule 01.04.2019