#c_sharp #async_await
Есть у меня promise метод чтения данных из моего потока: public void ReadAsync(AsyncReadCallback callback, AsyncException exception = null) { try { Thread thread = new Thread(new ThreadStart(() => { try { T request = ReadSync (); callback.Invoke(ref request); } catch(Exception e) { if(exception == null) { throw e; } exception.Invoke(e); } })); thread.Start(); } catch (Exception e) { if(exception == null) { throw e; } exception.Invoke(e); } } Вызывать я его могу, соответственно так: stream.ReadAsync((string result) => { Console.WriteLine("receive: "+result); },(Exception e) => { Console.WriteLine("exception: "+e.Message); }); Но, в погоне за сахаром, решил попробовать сделать аналогичное поведение через async, что даст возможность выполнять всё без потоков, более того, заставлять делать await в нужных мне местах: public async Task ReadAsync () { return ReadSync (); } Вызывать планирую, примерно так: Task taskRead = stream.ReadAsync (); ... string data = await taskRead; Console.WriteLine(data); Однако, VS2017 говорит, что мой код будет выполняться только синхронно, и что там нет await. Я не могу понять, возможно ли вообще то что я задумал? Вот что говорит сама студия (скрин очень неудобный): Всё что я хочу - выполнять синхронный метод так, как если бы он был асинхронен. (Возможно, звучит глупо, но, не могу сформулировать по другому)
Ответы
Ответ 1
Ключевое слово async позволяет выполнять асинхронное ожидание других задач (делать await), но простое добавление этого слова ничего не дает вам в плане многопоточности. Перемещение выполнения в другой поток все еще остается именно вашей задачей. Выполнить задачу в фоновом потоке можно при помощи Task.Run: public TaskReadAsync () { return Task.Run(() => ReadSync ()); } Однако, написание подобных оберток является дурной практикой: от асинхронного кода ожидается что он по крайней мере часть своей работы выполнит не занимая потока. Вероятно, правильным будет не делать отдельного метода ReadAsync - а вставить конструкцию Task.Run(() => ReadSync ()) непосредственно в том месте где вам нужно прочитать данные: Task taskRead = Task.Run(() => stream.ReadSync ()); ... string data = await taskRead; Console.WriteLine(data); А еще правильнее - переписать метод ReadSync так, чтобы он стал асинхронным.
Комментариев нет:
Отправить комментарий