當我回答你的previous question我假設你有一個使用TaskCompletionSource對象的需求,所以我很抱歉,如果這使你發現了錯誤的方向。正如Paulo曾經說過,你通常不需要使用TaskCompletionSource和async/await代碼,但你需要更多地瞭解如何使用它。
在任務上調用Result會導致該線程阻塞,現在在非UI線程中,這不是這樣的問題(只是不理想),但在UI線程中,這將有效地阻止您的UI from responding,直到任務假設它只是因爲僵局而沒有完全停止。
事情是要學習如何在UI環境中使用異步/等待,因爲要使它工作,你也必須使用異步/等待處處,否則最終會嘗試使用Task.Result來訪問數據並獲取一個阻塞的UI線程爲您的麻煩。
這是一個很好的入門指南 - https://msdn.microsoft.com/en-us/magazine/jj991977.aspx
現在假設你從這樣的頁面(從code samples在GitHub上的鵝卵石)拉動code
然後取令牌。
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
var content = webBrowser1.DocumentText;
var regex = new Regex(@"\<title\>(.+?)=(.+?)\</title\>");
var match = regex.Match(content);
if (!match.Success || match.Groups.Count != 3)
return;
switch (match.Groups[1].Value.ToLowerInvariant())
{
case "code": // we have a code
var code = match.Groups[2].Value;
var config = new ApiConfiguration(Configuration.ClientId, Configuration.ClientSecret, Configuration.RedirectUrl);
var service = new OAuthService(config, new WebRequestFactory(config));
var tokens = service.GetTokensAsync(code).Result; // <= blocking
_keyService.OAuthResponse = tokens;
break;
case "error": // user probably said "no thanks"
webBrowser1.Navigate(_logoffUri);
break;
}
}
但是你的代碼上阻塞.Result
你需要做的,當你使用等待它抱怨的方法缺乏異步的是使用異步/ AWAIT一路上揚但什麼,所以,只需添加它;是的,這是允許的,並且有許多關於這個的文章和博客文章catch people new to async/await在winforms/wpf UI中。
例如
// we add async to the callback - yup it's allowed
private async void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
var content = webBrowser1.DocumentText;
var regex = new Regex(@"\<title\>(.+?)=(.+?)\</title\>");
var match = regex.Match(content);
if (!match.Success || match.Groups.Count != 3)
return;
switch (match.Groups[1].Value.ToLowerInvariant())
{
case "code": // we have a code
var code = match.Groups[2].Value;
var config = new ApiConfiguration(Configuration.ClientId, Configuration.ClientSecret, Configuration.RedirectUrl);
var service = new OAuthService(config, new WebRequestFactory(config));
var tokens = await service.GetTokensAsync(code); // <= now we can use await here => non-blocking
_keyService.OAuthResponse = tokens;
break;
case "error": // user probably said "no thanks"
webBrowser1.Navigate(_logoffUri);
break;
}
}
我已經uploaded the code as gist我希望它能幫助
@shaun_a_wilde請你能幫忙嗎? –
什麼UI?如果它是基於WinForms或WPF的消息泵,則會阻止它。你爲什麼使用'Task.Run'和'TaskCompletionSource'來調用已經異步的代碼? –
我編輯了這個問題,以澄清它是鎖定的程序而不是UI。 (我必須按Ctrl Alt Delete結束程序)。我正在使用Task.Run和TaskCompletionSource以等待任務運行。有一個同步選項.GetTokens,但我正在嘗試。 –