C# MYOB oauthService.GetTokenAsync不显示对话框
由于我的问题 我尝试了一种类似的技术来获得代币C# MYOB oauthService.GetTokenAsync不显示对话框,c#,oauth,async-await,myob,taskcompletionsource,C#,Oauth,Async Await,Myob,Taskcompletionsource,由于我的问题 我尝试了一种类似的技术来获得代币 private t.Task<OAuthTokens> GetOAuthTokens() { var tcs = new t.TaskCompletionSource<OAuthTokens>(); t.Task.Run( async () => { var oauthService = new OA
private t.Task<OAuthTokens> GetOAuthTokens()
{
var tcs = new t.TaskCompletionSource<OAuthTokens>();
t.Task.Run(
async () =>
{
var oauthService = new OAuthService(_configurationCloud);
var code = OAuthLogin.GetAuthorizationCode(_configurationCloud);
var response = await oauthService.GetTokensAsync(code);
tcs.SetResult(response);
});
return tcs.Task;
}
但是,当我运行程序时,它会锁定
以下工作正常
var oauthService = new OAuthService(_configurationCloud);
var code = OAuthLogin.GetAuthorizationCode(_configurationCloud); // causes a login dialog
var tokens = oauthService.GetTokens(code);
_oAuthKeyService.OAuthResponse = tokens;
并打开授权对话框。当我回答您的问题时,我假设您需要使用TaskCompletionSource对象,因此如果这让您走错了方向,我很抱歉。如前所述,您通常不需要将TaskCompletionSource与异步/等待代码一起使用,但您确实需要进一步了解如何使用它
调用任务将导致该线程阻塞,现在在非UI线程中这不是一个问题(只是不理想),但在UI线程中,这将有效地停止您的线程,直到任务完成为止,假设它没有因为死锁而完全停止
关键是要学习如何在UI环境中使用async/await,因为要让它正常工作,您必须在任何地方都使用async/await,否则您将尝试使用Task.Result访问数据,并获得阻塞的UI线程以解决问题
这是一个很好的入门指南-
现在我假设您像这样从页面中提取code
(从GitHub上拼凑而成),然后提取令牌
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;
}
}
当我回答您的问题时,我认为您有使用TaskCompletionSource对象的要求,因此如果这让您走错了方向,我很抱歉。如前所述,您通常不需要将TaskCompletionSource与异步/等待代码一起使用,但您确实需要进一步了解如何使用它
调用任务将导致该线程阻塞,现在在非UI线程中这不是一个问题(只是不理想),但在UI线程中,这将有效地停止您的线程,直到任务完成为止,假设它没有因为死锁而完全停止
关键是要学习如何在UI环境中使用async/await,因为要让它正常工作,您必须在任何地方都使用async/await,否则您将尝试使用Task.Result访问数据,并获得阻塞的UI线程以解决问题
这是一个很好的入门指南-
现在我假设您像这样从页面中提取code
(从GitHub上拼凑而成),然后提取令牌
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;
}
}
我希望这会有帮助@shaun_a_wilde你能帮忙吗?什么用户界面?如果它是基于消息泵的,比如WinForms或WPF,那么它将被阻塞。为什么要使用
Task.Run
和TaskCompletionSource
调用已经异步的代码?我编辑了这个问题,以澄清锁定的是程序,而不是UI。(我必须按Ctrl-Alt-Delete键才能结束程序)。我正在使用Task.Run和TaskCompletionSource以等待任务运行。有一个同步选项。GetTokens,但我正在试验。你能显示调用代码吗?它是一个事件处理程序吗?我在“使用@shaun_a_wilde调用它”的问题中包含了它。你能帮忙吗?什么UI?如果它是基于消息泵的,比如WinForms或WPF,那么它将被阻塞。为什么要使用Task.Run
和TaskCompletionSource
调用已经异步的代码?我编辑了这个问题,以澄清锁定的是程序,而不是UI。(我必须按Ctrl-Alt-Delete键才能结束程序)。我正在使用Task.Run和TaskCompletionSource以等待任务运行。有一个同步选项。GetTokens,但我正在试验。你能显示调用代码吗?它是一个事件处理程序吗?我把它包含在“使用调用”下的问题中,谢谢Shaun。我得到以下块:var tokens=service.GetTokensAsync(code.Result);我知道我可以使用service.GetTokens()代替,这也会阻塞。我不明白的是,为什么登录对话框只在我使用service.GetTokens()时出现。当我使用Async选项时,程序将锁定,并且从不解锁。这就好像登录对话框是不可见的。@kirsteng-提供的小片段很难说-GetTokens实现在github上实际上使用了一种不依赖于async/await模式的替代异步方法-因此它可以用于没有async/await的框架版本,例如.NET2。谢谢Shaun,我现在将使用非异步版本的GetTokens()。谢谢Shaun。我得到以下块:var tokens=service.GetTokensAsync(code.Result);我知道我可以使用service.GetTokens()代替,这也会阻塞。我不明白的是,为什么登录对话框只在我使用service.GetTokens()时出现。当我使用Async选项时,程序将锁定,并且从不解锁。这就好像登录对话框是不可见的。@kirsteng-提供的小片段很难说-GetTokens实现在github上实际上使用了一种不依赖于async/await模式的替代异步方法-因此它可以用于没有async/await的框架版本,例如.NET2。谢谢Shaun,我现在将使用非异步版本的GetTokens()。
// 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;
}
}