当我回答你之前的问题时,我假设你需要使用 TaskCompletionSource 对象,所以如果这让你走错了方向,我很抱歉。正如Paulo所说,您通常不需要将 TaskCompletionSource 与 async/await 代码一起使用,但您确实需要更多地了解如何使用它。
在任务上调用Result将导致该线程阻塞,现在在非 UI 线程中这不是这样的问题(只是不理想),但在 UI 线程中,这将有效地阻止您的UI 响应,直到任务完成,假设它只是由于死锁而没有完全停止。
问题是要学习如何在 UI 环境中使用 async/await,因为要让它工作,你必须在任何地方都使用 async/await,否则你最终会尝试使用 Task.Result 来访问你的数据并获得阻塞的 UI 线程为你的烦恼。
这是一个很好的入门指南 - https://msdn.microsoft.com/en-us/magazine/jj991977.aspx
现在我假设您正在像这样从页面中提取(从 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
您需要做的是一直使用 async/await ,但是当您使用 await 时,它会抱怨该方法缺少异步,所以,只需添加它;是的,这是允许的,并且有许多关于此的文章和博客文章吸引了新的 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;
}
}
我已将代码作为要点上传,希望对您有所帮助