MYOB oauthService.GetTokensAsync 未显示对话框
MYOB oauthService.GetTokensAsync not showing dialog
由于我的问题
我尝试了类似的技术来获取令牌
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 task1 = GetOAuthTokens();
_oAuthKeyService.OAuthResponse = task1.Result;
但是,当我 运行 时程序锁定了。
以下作品OK
var oauthService = new OAuthService(_configurationCloud);
var code = OAuthLogin.GetAuthorizationCode(_configurationCloud); // causes a login dialog
var tokens = oauthService.GetTokens(code);
_oAuthKeyService.OAuthResponse = tokens;
并弹出授权对话框。
当我回答你的时候 I assumed you had a requirement to use a TaskCompletionSource object so I am sorry if this has sent you in the wrong direction. As Paulo 说你通常不需要将 TaskCompletionSource 与 async/await 代码一起使用,但你确实需要更多地了解如何使用它。
调用 Result on a Task will cause that thread to block, now in a non-UI thread this isn't such an issue (just not ideal) but in a UI thread this will effectively stop your UI from responding 直到任务完成,假设它只是由于死锁而没有完全停止。
关键是要学习如何在 UI 环境中使用 async/await,因为要让它工作,你必须在任何地方都使用 async/await,否则你最终会尝试使用Task.Result 访问您的数据并获得一个被阻止的 UI 线程来解决您的麻烦。
这是一个很好的入门指南 - https://msdn.microsoft.com/en-us/magazine/jj991977.aspx
现在我假设您正在像这样从页面中提取 code
(从 GitHub 上的 code samples 拼凑而成),然后获取令牌。
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 时它会抱怨该方法缺少异步,因此,只需添加它;是的,这是允许的,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希望对你有帮助
由于我的问题
我尝试了类似的技术来获取令牌
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 task1 = GetOAuthTokens();
_oAuthKeyService.OAuthResponse = task1.Result;
但是,当我 运行 时程序锁定了。
以下作品OK
var oauthService = new OAuthService(_configurationCloud);
var code = OAuthLogin.GetAuthorizationCode(_configurationCloud); // causes a login dialog
var tokens = oauthService.GetTokens(code);
_oAuthKeyService.OAuthResponse = tokens;
并弹出授权对话框。
当我回答你的时候
调用 Result on a Task will cause that thread to block, now in a non-UI thread this isn't such an issue (just not ideal) but in a UI thread this will effectively stop your UI from responding 直到任务完成,假设它只是由于死锁而没有完全停止。
关键是要学习如何在 UI 环境中使用 async/await,因为要让它工作,你必须在任何地方都使用 async/await,否则你最终会尝试使用Task.Result 访问您的数据并获得一个被阻止的 UI 线程来解决您的麻烦。
这是一个很好的入门指南 - https://msdn.microsoft.com/en-us/magazine/jj991977.aspx
现在我假设您正在像这样从页面中提取 code
(从 GitHub 上的 code samples 拼凑而成),然后获取令牌。
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 时它会抱怨该方法缺少异步,因此,只需添加它;是的,这是允许的,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希望对你有帮助