В настоящее время я пытаюсь создать свое приложение, используя некоторые методы Async. Все мои операции ввода-вывода выполняются с помощью явных реализаций интерфейса, и я немного не понимаю, как сделать операции асинхронными.
Насколько я понимаю, у меня есть два варианта реализации:
interface IIO
{
void DoOperation();
}
ВАРИАНТ 1. Выполните неявную реализацию async и дождитесь результата в неявной реализации.
class IOImplementation : IIO
{
async void DoOperation()
{
await Task.Factory.StartNew(() =>
{
//WRITING A FILE OR SOME SUCH THINGAMAGIG
});
}
#region IIO Members
void IIO.DoOperation()
{
DoOperation();
}
#endregion
}
ВАРИАНТ 2. Выполните явную асинхронную реализацию и дождитесь выполнения задачи из неявной реализации.
class IOAsyncImplementation : IIO
{
private Task DoOperationAsync()
{
return new Task(() =>
{
//DO ALL THE HEAVY LIFTING!!!
});
}
#region IIOAsync Members
async void IIO.DoOperation()
{
await DoOperationAsync();
}
#endregion
}
Одна из этих реализаций лучше другой или есть другой способ, о котором я не думаю?
источник
async
):async Task IIO.DoOperationAsync()
. И вы имеете в виду, откуда выawait
вернулисьTask
? Куда бы вы ни позвонилиDoOperationAsync()
.Task.Run()
, этот код ввода-вывода должен быть асинхронным, и вы должны это делатьawait
напрямую. Напрline = await streamReader.ReadLineAsync()
.Лучшее решение - ввести другой интерфейс для асинхронных операций. Новый интерфейс должен быть унаследован от исходного интерфейса.
Пример:
PS Измените дизайн своих асинхронных операций, чтобы они возвращали Task вместо void, если только вы действительно не должны возвращать void.
источник
GetAwaiter().GetResult()
вместоWait()
? Таким образом, вам не нужно распаковывать,AggregateException
чтобы получить внутреннее исключение.class Impl : IIO, IIOAsync
. Однако сами IIO и IIOAsync представляют собой разные контракты, которые позволяют избежать втягивания «старых контрактов» в новый код.var c = new Impl(); IIOAsync asAsync = c; IIO asSync = c
.Вместо интерфейса можно использовать абстрактный класс (в C # 7.3).
источник
IIO.DoOperation()
вместоabstract
самой себя есть фиктивная реализация ?abstract
если нетabstract
членов.DoOperation()
Метод может быть сделаноabstract
, но тогда у вас есть что - то , что, по существу , только интерфейс. Это возвращает нас к тому, почему бы просто не использовать интерфейс? Приведенный выше код бессмыслен. :(abstract async
. Единственное, чтоasync
делает добавление к объявлению метода, - это возможность использовать егоawait
в методе. Если ваш метод не используетсяawait
, значит, вам не нужноasync
. Вот почему в первую очередь работает интерфейсный подход; что действительно важно, так это возвращаемый тип . Вы можете сделать возвращаемый типTask<string>
безasync
ключевого слова.