Задача первая: асинхронное / ожидание
private async void TestAsync(string origin)
{
await LongTask();
}
Пояснение:
Когда вызывается делегат события нажатия кнопки, он вызывается из главного диспетчера (поток пользовательского интерфейса). Он говорит делегату о необходимости вызова TestAsync("Fab")
Синхронно. Когда делегат проходит через тестовый асинхронный метод, ему предписывают запустить задачу LongTask
, но вы также говорите ему дождаться результата этой задачи с помощью запроса 'await'. Таким образом, метод TestAsync
не может завершиться, пока не будет завершен LongTask
; так как это запрашивается у главного диспетчера, остальная часть пользовательского интерфейса зависает до его завершения.
Разрешение:
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
// [...]
_fab = root.FindViewById<FloatingActionButton>(...);
_fab.Click += ((sender, v) => TestAsync("fab"));
// [...]
}
private async void TestAsync(string origin)
{
// By not calling await you tell the code that you don't need this
// calling method to await a return value.
// using Task.Run explicitly requests another thread process this request
Task.Run(LongTask);
}
private async Task LongTask()
{
while (true) { } // Thread should hung here
}
Задача вторая: Сеть
public async Task<int> Network(string s)
{
URL url = new URL("http://www.randomtext.me/api/");
Java.IO.BufferedReader reader = new Java.IO.BufferedReader(new Java.IO.InputStreamReader(url.OpenStream()));
int count = 0;
string str;
while ((str = reader.ReadLine()) != null) {
count += str.Length;
}
reader.Close();
await Task.Delay(3000); // To make sure this method is compiled as async even though it isn't necessary
return count;
}
Пояснение:
Как и прежде, это во многом зависит от того, как запускается задача, см. Эту цитату из документации Microsoft:
Ключевые слова async и await не приводят к созданию дополнительных потоков.
создано. Асинхронные методы не требуют многопоточности, потому что асинхронные
метод не работает в своем собственном потоке. Метод работает на текущем
контекст синхронизации и использует время в потоке, только когда
метод активен. Вы можете использовать Task.Run для перемещения работы с процессором в
фоновый поток, но фоновый поток не помогает с процессом
это только ожидание результатов, чтобы стать доступными.
Я надеюсь, что этот ответ добавляет немного больше деталей, которые будут использоваться наряду с другими ответами на ваш вопрос.