Есть у меня promise метод чтения данных из моего потока:
public void ReadAsync<T>(AsyncReadCallback<T> callback, AsyncException exception = null) {
try {
Thread thread = new Thread(new ThreadStart(() => {
try {
T request = ReadSync<T>();
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<T> ReadAsync<T>() {
return ReadSync<T>();
}
Вызывать планирую, примерно так:
Task<string> taskRead = stream.ReadAsync<string>();
...
string data = await taskRead;
Console.WriteLine(data);
Однако, VS2017 говорит, что мой код будет выполняться только синхронно, и что там нет await. Я не могу понять, возможно ли вообще то что я задумал?
Вот что говорит сама студия (скрин очень неудобный): Всё что я хочу - выполнять синхронный метод так, как если бы он был асинхронен. (Возможно, звучит глупо, но, не могу сформулировать по другому)
Ключевое слово async позволяет выполнять асинхронное ожидание других задач (делать await), но простое добавление этого слова ничего не дает вам в плане многопоточности. Перемещение выполнения в другой поток все еще остается именно вашей задачей.
Выполнить задачу в фоновом потоке можно при помощи Task.Run:
public Task<T> ReadAsync<T>() {
return Task.Run(() => ReadSync<T>());
}
Однако, написание подобных оберток является дурной практикой: от асинхронного кода ожидается что он по крайней мере часть своей работы выполнит не занимая потока.
Вероятно, правильным будет не делать отдельного метода ReadAsync - а вставить конструкцию Task.Run(() => ReadSync<T>()) непосредственно в том месте где вам нужно прочитать данные:
Task<string> taskRead = Task.Run(() => stream.ReadSync<T>());
...
string data = await taskRead;
Console.WriteLine(data);
А еще правильнее - переписать метод ReadSync так, чтобы он стал асинхронным.
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости