У меня есть программа на vb.net (VS 2017), использующая фреймворк 4.7, где функция занимает слишком много времени для обработки, прерывая перекачку сообщений и вызывая ошибку тайм-аута. Чтобы решить эту проблему, я хочу запустить функцию асинхронно, используя задачи и ожидание. (в новинку для меня). Я понимаю, что для этого мне нужно создать асинхронную функцию (с использованием ключевого слова async), которая использует ожидание для вызова другой асинхронной функции, которая затем выполняет обработку. Проблема в том, как сделать мою собственную функцию асинхронной, которая внутри не использует предопределенный асинхронный процесс, вызываемый await. Для этого мне, кажется, нужно определить GetAwaiter для моей функции, чтобы сделать ее вызываемой с помощью await. Вот где я в тупике. Я искал в Интернете и искал книги по этой теме, и у меня не получилось. Все веб-примеры написаны на C# (с которым я не очень разбираюсь), и я не могу осмыслить примеры кода C#, которые я нашел для создания GetAwaiter. Например, из блога Стивена Туба:
public static TaskAwaiter GetAwaiter(this DateTimeOffset dateTimeOffset)
{
return (dateTimeOffset – DateTimeOffset.UtcNow).GetAwaiter();
}
чтобы создать GetAwaiter для функции DateTimeOffset. Мне не понятна декларативная строка, в частности двойник TaskAwaiter GetAwaiter и содержимое скобок, следующих за ключевым словом GetAwaiter. Я действительно думаю, что «this» относится к отправителю в vb, DateTimeOffset - это имя функции, получающей GetAwaiter, а dateTimeOffset - это передаваемое значение, но я не понимаю эту комбинацию имен функций и значений внутри парена. Как эту строчку можно переписать на vb? Существуют ли какие-либо хорошие, исчерпывающие книги, статьи и т. д., Охватывающие функциональность задачи / ожидания - особенно когда вам нужно создать новую асинхронную функцию, которая не была предварительно упакована и не включена как часть .net и написана с примерами vb. Я нашел очень информативную презентацию Майкла Кеннеди на YouTube, но, как и во всех других найденных мною примерах, она основана на предопределенной асинхронной функции, которую можно вызвать с помощью await. Мне нужно поднять голову над водой - где поверхность?
Кроме того, вы действительно хотите сделать методы асинхронными только в том случае, если есть причина сделать их асинхронными (например, попадание в базу данных, выполнение сетевого вызова, попадание на диск, ожидание таймера). Что касается ввода-вывода, обычно вы будете использовать библиотеку, в которую она уже встроена - большая часть операций ввода-вывода уже асинхронна на уровне ОС.
Для меня это всего лишь основа для создания GetAwaiter, фактическая функциональность для меня несущественна, так как я бы использовал свой собственный код. Меня больше всего интересует, как этот фреймворк может быть написан на VB, поэтому я могу создавать GetAwaiters по мере необходимости для покрытия трудоемких процессов. Спасибо за информацию об этом ключевом слове, я изучу это и кое-что узнаю.
Что ж, я придумал решение - не то, что я хотел, но такое, которое, кажется, преодолевает мое самое большое препятствие, а именно возможность запускать неасинхронную функцию, которая не полагается на ожидание внутри внутри структуры async-await. . Я предусмотрел передачу значений и возврат значения - в данном случае передачу строки и возврат логического значения. В итоге я использовал вызов task.run - см. Следующий комментарий
В основной подпрограмме я сделал ее асинхронной и вызвал асинхронную функцию, используя await Private Async Sub MyProgAsync () dim aBool as boolean = await myFuncAsync (string) Внутри этой функции я использовал task.run: private Async Function myFuncAsync (byval pcValue as string ) как логическое dim lReturn как boolean = await Task (of Boolean) .Run (Function () myTask (pcValue) Return lReturn
Это позволило мне вызвать myTask, передать строковый параметр и вернуть логический ответ, который прошел вверх и вниз по цепочке, а myTask не является Async и не использует ожидание. Тем не менее основная программа запускает цепочку в новый поток, сохраняя при этом поток пользовательского интерфейса активным. Я все еще хочу узнать, как написать GetAwaiter для функции, которую я мог бы написать, чтобы я мог вызывать ее напрямую с помощью await, а не с помощью task.run. Мы будем очень благодарны за любые предложения относительно книг, статей, видео и т. д. (Используя vb, если возможно).
Фрагмент кода, которым вы поделились, мне кажется подозрительным. Ключевое слово
this
означает, что функция является методом расширения. ВычитаниеDateTimeOffsets
возвращаетTimeSpan
, который не имеет встроенного методаGetAwaiter
. Кроме того, это не совсем тот метод, который вам может понадобиться для асинхронной обработки.