C# 获取Graph API的访问令牌在控制台应用程序中有效,但在窗体应用程序中挂起
我可以使用控制台应用程序成功获取用于对Graph API进行身份验证的访问令牌,但是,当尝试使用Windows forms应用程序实现相同代码时,它挂起在以下行:C# 获取Graph API的访问令牌在控制台应用程序中有效,但在窗体应用程序中挂起,c#,winforms,asynchronous,microsoft-graph-api,C#,Winforms,Asynchronous,Microsoft Graph Api,我可以使用控制台应用程序成功获取用于对Graph API进行身份验证的访问令牌,但是,当尝试使用Windows forms应用程序实现相同代码时,它挂起在以下行:result=wait app.AcquireTokenForClient(scope.ExecuteAsync() 我尝试了与以下代码不同的方法,例如使用Microsoft Graph SDK,它再次在控制台应用程序中工作,导致访问代码位于result.AccessToken中,这样我就可以调用Graph API,但是result=w
result=wait app.AcquireTokenForClient(scope.ExecuteAsync()代码>
我尝试了与以下代码不同的方法,例如使用Microsoft Graph SDK,它再次在控制台应用程序中工作,导致访问代码位于result.AccessToken中,这样我就可以调用Graph API,但是result=wait app.AcquireTokenForClient(scope.ExecuteAsync()代码>在表单应用程序中使用时不完整
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using Microsoft.Identity.Client;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace SimpleOnePagerConsole
{
class Program
{
static void Main(string[] args)
{
RunAsync().GetAwaiter().GetResult();
}
private static async Task RunAsync()
{
var clientId = "76a824c0-4dce-xxxx-xxxx-xxxxxxxxxxxx";
var tenantId = "xxxxxxxxxxxx.onmicrosoft.com";
var clientSecret = "B-0PWoQHPK1_-xxxxxxxxxxxxxxxxxxxx";
var scope = new string[] { "https://graph.microsoft.com/.default" };
IConfidentialClientApplication app;
app = ConfidentialClientApplicationBuilder.Create(clientId)
.WithClientSecret(clientSecret)
.WithTenantId(tenantId)
.Build();
AuthenticationResult result = null;
try
{
result = await app.AcquireTokenForClient(scope)
.ExecuteAsync();
}
}
}
}
我完全预料到,在使用表单应用程序时,在异步/等待方面我缺少了一些东西,我感谢您提供的任何帮助
编辑:下面是挂起在我前面提到的“ExecuteAsync()”上的一些代码
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.Identity.Client;
namespace SimpleFormsApp
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void getToken_Click(object sender, EventArgs e)
{
RunAsync().GetAwaiter().GetResult();
}
public static async Task RunAsync()
{
var clientId = "76a824c0-4dce-xxxx-xxxx-xxxxxxxxxxxx";
var tenantId = "xxxxxxxxxxxx.onmicrosoft.com";
var clientSecret = "B-0PWoQHPK1_-xxxxxxxxxxxxxxxxxxxx";
var scope = new string[] { "https://graph.microsoft.com/.default" };
IConfidentialClientApplication app;
app = ConfidentialClientApplicationBuilder.Create(clientId)
.WithClientSecret(clientSecret)
.WithTenantId(tenantId)
.Build();
AuthenticationResult result = null;
try
{
MessageBox.Show("Getting Token");
result = await app.AcquireTokenForClient(scope)
.ExecuteAsync();
MessageBox.Show(result.AccessToken);
}
catch
{
MessageBox.Show("Ended up in catch block");
}
}
}
}
正如在的MSDN文章-或他的文章中所述,您正在导致代码死锁。你可以阅读他的博客和我上面链接的MSDN文章
事件处理程序是async/await
中规则的1个例外,您可以将方法getToken\u Click(object sender,EventArgs e)
标记为async void
,因此更改为该方法将消除死锁问题:
private async void getToken_Click(object sender, EventArgs e)
{
await RunAsync();
}
此外,如果要从方法返回令牌,可能需要更改为返回任务
,其中T
是令牌的对象类型:
public static async Task<T> RunAsync()
公共静态异步任务RunAsync()
不要发布控制台应用程序的工作代码,而是发布表单应用程序不工作的代码。使用我组装的快速表单应用程序修改我的帖子。非常感谢,伙计,这非常有效。我一定会去读你提到的两篇文章。我觉得我现在可以修改我真正的应用程序,开始使用表单应用程序进行图形调用。再次感谢你。@Ashdmckenzie没问题。很高兴我能帮忙。我一直在努力解决async/await
,Stephen很友好地向我解释了其中的一些问题。只是想把钱预付。快乐编码。