Просто получил VS2012 и попытался получить дескриптор на async
.
Скажем, у меня есть метод, который извлекает некоторое значение из источника блокировки. Я не хочу, чтобы вызывающий метод блокировал. Я мог бы написать метод для выполнения обратного вызова, который вызывается при достижении значения, но поскольку я использую С# 5, я решил сделать метод async, чтобы вызывающие абоненты не имели дело с обратными вызовами:
// contrived example (edited in response to Servy comment)
public static Task<string> PromptForStringAsync(string prompt)
{
return Task.Factory.StartNew(() => {
Console.Write(prompt);
return Console.ReadLine();
});
}
Вот пример метода, который его вызывает. Если PromptForStringAsync
не был асинхронным, этот метод потребовал бы вставки обратного вызова в обратном вызове. С async я могу написать свой метод самым естественным образом:
public static async Task GetNameAsync()
{
string firstname = await PromptForStringAsync("Enter your first name: ");
Console.WriteLine("Welcome {0}.", firstname);
string lastname = await PromptForStringAsync("Enter your last name: ");
Console.WriteLine("Name saved as '{0} {1}'.", firstname, lastname);
}
Пока все хорошо. Проблема заключается в том, что я вызываю GetNameAsync:
public static void DoStuff()
{
GetNameAsync();
MainWorkOfApplicationIDontWantBlocked();
}
Вся точка GetNameAsync
заключается в том, что она асинхронна. Я не хочу, чтобы он блокировался, потому что я хочу вернуться к MainWorkOfApplicationIDontWantBlocked ASAP и позволить GetNameAsync делать свое дело в фоновом режиме. Тем не менее, вызов этого метода дает мне предупреждение компилятора в строке GetNameAsync
:
Warning 1 Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
Я прекрасно понимаю, что "выполнение текущего метода продолжается до завершения вызова". Что точка асинхронного кода, правильно?
Я предпочитаю, чтобы мой код компилировался без предупреждений, но здесь нечего "исправлять", потому что код выполняет именно то, что я намереваюсь сделать. Я могу избавиться от предупреждения, сохранив возвращаемое значение GetNameAsync
:
public static void DoStuff()
{
var result = GetNameAsync(); // supress warning
MainWorkOfApplicationIDontWantBlocked();
}
Но теперь у меня есть лишний код. Visual Studio, похоже, понимает, что я был вынужден написать этот ненужный код, потому что он подавляет обычное предупреждение "значение никогда не используется".
Я также могу избавиться от предупреждения, обернув GetNameAsync в методе, который не async:
public static Task GetNameWrapper()
{
return GetNameAsync();
}
Но это еще более лишний код. Поэтому мне нужно написать код, который мне не нужен, или терпеть ненужное предупреждение.
Есть ли что-то в моем использовании async, что здесь неправильно?