2016-10-20 3 views
0

Я прочитал много руководств касаемо ждать/асинхронные и я понял, что, когда дело доходит до await ключевого слова будет вернуться к main context затем вернуться к await (когда он закончен), а затем продолжить дальше, если есть что-то после away в пределах async. Я также читал, что есть что-то вроде ConfigureAwait(False), что просто означает, что в отличие от того, что я написал раньше, когда дело доходит до await, он не вернется к main context в этот момент, но останется здесь и будет ждать, пока await будет закончен, а затем продолжить в async метод после этого вернется к main cotext. Таким образом, это не будет возвращаться к main context, но подождите await. Правильно, если я ошибаюсь. На основе этих знаний в первом примере я должен увидеть следующий результат:ConfigureAwait Task (в False) не работает

After DoStafAsync 
Done running the long operation asynchronously. 

но когда я просто добавить ConfigureAwait (False) должно быть:

Done running the long operation asynchronously. 
After DoStafAsync 

, поскольку он не будет возвращаться к контексту, но будет ждать и после завершения асинхронного метода, то вернется. Как-то я вижу результат как в первом выпуске. Что мне не хватает?

Public Class Form1 

    Sub LongOperation() 
     Threading.Thread.Sleep(5000) 
    End Sub 

    Private Async Function DoStafAsync() As Task 
     lblStatus.Text = "Running a long operation asynchronously... (UI thread should be fully responsive)" 
     Await Task.Run(Sub() 
          LongOperation() 
         End Sub).ConfigureAwait(False) 

     lblStatus.Text = "Done running the long operation asynchronously." 
    End Function 

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load  
     dfg 
     lblStatus.Text = "After DoStafAsync" 
    End Sub 

    Async Sub Dfg 
     Await DoStafAsync 
    End Sub 

End Class 

Дополнительный вопрос: Некоторые люди утверждают, что задачи не создают темы, но работает на той же Ui нити. Но есть некоторые люди , утверждая, что они есть, и есть также люди, утверждающие, что иногда выполняет задачи создания потоков, а иногда нет. Что здесь верно?

+0

Эрик Липперт написал несколько замечательных сообщений ** об этом. [Как этот] (http://stackoverflow.com/a/10034608/1070452) этот [эпический] (http: // stackoverflow.com/a/39522149/1070452) – Plutonix

+0

@Plutonix ok, но я все еще не вижу проблемы в моем коде, а для задач второго случая не создаются ступени? –

+0

@Plutonix любая обратная связь? –

ответ

0

я уже понял, что, когда дело доходит до ждет ключевого слова будет вернуться к главному контексту затем вернуться в ожидание (когда она будет закончена), а затем продолжить дальше, если есть что-то после того, как далеко в методе асинхронной.

Я не думаю, что вы используете термин «контекст» так, как обычно используется при объяснении асинхронного кода. Посмотрите мой async intro blog post, в котором точно объясняется, что такое контекст и как он используется await.

В частности, «контекст» делает не означает «метод или функция». Он не определяет, как и когда код возвращается к другой части кода.

Возможно, вы также захотите прочитать мой номер MSDN article on async best practices, в котором объясняется, почему вам следует избегать асинхронных ошибок (кроме обработчиков событий). Если вы сделаете Form1_Load асинхронные пустоты и избавиться от dfg, то он работает, как и следовало ожидать:

Private Async Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load  
    Await DoStafAsync 
    lblStatus.Text = "After DoStafAsync" 
End Sub 

Причина, по которой не работали до того, потому что Form1_Load не ждет dfg (или DoStafAsync) для завершения - он просто уволил их, а затем немедленно приступил к настройке текста ярлыка. Как я указываю в своей статье о лучших практиках, одна из основных проблем с async void (async sub) заключается в том, что вызывающий код не может определить, когда он завершил (по крайней мере, не так просто).

+0

привет, я получаю тогда ошибку или Await DoStafAsync: Invalid Operation Exception: Дополнительная информация: Неверная операция кросс-потоков: Control 'lblStatus' доступен из потока, отличного от потока, на котором он был создан. –

+0

делает это, потому что, если я отмечен как .ConfigureAwait (False), тогда эта строка: lblStatus.Text = "Выполняется длительная операция асинхронно." пытается быть вызван из пула потоков правильно? –

+0

, поэтому я просто не могу сделать это, когда захочу использовать .ConfigureAwait (False) \? –

Смежные вопросы