Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从非异步方法运行异步代码_C#_Asynchronous_Async Await - Fatal编程技术网

C# 从非异步方法运行异步代码

C# 从非异步方法运行异步代码,c#,asynchronous,async-await,C#,Asynchronous,Async Await,我正在尝试从Azure AD获取访问令牌,而异步调用从未完成。我不确定我做错了什么,也许有人能给我指出正确的方向。代码如下: private static void GetAccessTokenNonAsync() { Func<System.Threading.Tasks.Task> task = async () => { await GetAccessToken().ConfigureAwait(false); }; task().

我正在尝试从Azure AD获取访问令牌,而异步调用从未完成。我不确定我做错了什么,也许有人能给我指出正确的方向。代码如下:

private static void GetAccessTokenNonAsync()
    {
        Func<System.Threading.Tasks.Task> task = async () => { await GetAccessToken().ConfigureAwait(false); };
        task().Wait();
    }
    private static async Task<AuthenticationResult> GetAccessToken()
    {
        string aadInstance = ConfigurationManager.AppSettings["ida:AADInstance"];
        string clientId = ConfigurationManager.AppSettings["ida:ClientId"];
        string clientSecret = ConfigurationManager.AppSettings["ida:ClientSecret"];
        string source = ConfigurationManager.AppSettings["ExchangeOnlineId"];

        var authContext = new AuthenticationContext(aadInstance, false);
        var credentials = new ClientCredential(clientId, clientSecret);
        var appRedirectUrl = HttpContext.Current.GetOwinContext().Request.Scheme + "://" + HttpContext.Current.GetOwinContext().Request.Host + HttpContext.Current.GetOwinContext().Request.PathBase + "/";
        var res =
             await
                 authContext.AcquireTokenByAuthorizationCodeAsync(
                     ((ClaimsIdentity)HttpContext.Current.User.Identity).FindFirst("AuthenticationCode").Value,
                     new Uri(appRedirectUrl), credentials, source).ConfigureAwait(false);
        Current.AccessToken = res.AccessToken;
        return res;

    }
    private static string AccessToken
    {
        get
        {
            return HttpContext.Current.Session["AccessToken"].ToString();
        }
        set { HttpContext.Current.Session["AccessToken"] = value; }
    }
private static void GetAccessTokenNonAsync()
{
Func task=async()=>{await GetAccessToken().ConfigureAwait(false);};
task().Wait();
}
私有静态异步任务GetAccessToken()
{
字符串aadInstance=ConfigurationManager.AppSettings[“ida:aadInstance”];
字符串clientId=ConfigurationManager.AppSettings[“ida:clientId”];
字符串clientSecret=ConfigurationManager.AppSettings[“ida:clientSecret”];
字符串源=ConfigurationManager.AppSettings[“ExchangeOnlineId”];
var authContext=新的AuthenticationContext(aadInstance,false);
var-credentials=新的ClientCredential(clientId,clientSecret);
var appRedirectUrl=HttpContext.Current.GetOwinContext().Request.Scheme+“:/”+HttpContext.Current.GetOwinContext().Request.Host+HttpContext.Current.GetOwinContext().Request.PathBase+“/”;
var res=
等待
authContext.AcquireTokenByAuthorizationCodeAsync(
((ClaimsIdentity)HttpContext.Current.User.Identity).FindFirst(“AuthenticationCode”).Value,
新Uri(appRedirectUrl)、凭据、源);
Current.AccessToken=res.AccessToken;
返回res;
}
私有静态字符串AccessToken
{
得到
{
返回HttpContext.Current.Session[“AccessToken”].ToString();
}
设置{HttpContext.Current.Session[“AccessToken”]=value;}
}

在我的main方法中,我调用GetAccessTokenNonAsync()

您不正确地使用了async关键字。像这样的方法应该会奏效:

public static void GetAccessTokenNonAsync()
{
    // Call the async method and get the resulting task.
    Task<AuthenticationResult> accessTokenTask = GetAccessToken();
    // Wait for the task to finish.
    accessTokenTask.Wait();
}

private async static Task<AuthenticationResult> GetAccessToken()
{
    return await Task.Factory.StartNew<AuthenticationResult>
    (
        () =>
        {
            // Insert code here.
            return new AuthenticationResult();
        }
    );
}
公共静态void GetAccessTokenNonAsync()
{
//调用async方法并获取结果任务。
Task accessTokenTask=GetAccessToken();
//等待任务完成。
accessTokenTask.Wait();
}
私有异步静态任务GetAccessToken()
{
return wait Task.Factory.StartNew
(
() =>
{
//在这里插入代码。
返回新的AuthenticationResult();
}
);
}

您未正确使用async关键字。像这样的方法应该会奏效:

public static void GetAccessTokenNonAsync()
{
    // Call the async method and get the resulting task.
    Task<AuthenticationResult> accessTokenTask = GetAccessToken();
    // Wait for the task to finish.
    accessTokenTask.Wait();
}

private async static Task<AuthenticationResult> GetAccessToken()
{
    return await Task.Factory.StartNew<AuthenticationResult>
    (
        () =>
        {
            // Insert code here.
            return new AuthenticationResult();
        }
    );
}
公共静态void GetAccessTokenNonAsync()
{
//调用async方法并获取结果任务。
Task accessTokenTask=GetAccessToken();
//等待任务完成。
accessTokenTask.Wait();
}
私有异步静态任务GetAccessToken()
{
return wait Task.Factory.StartNew
(
() =>
{
//在这里插入代码。
返回新的AuthenticationResult();
}
);
}

由于异步代码返回某些内容(使用任务签名),如果您的目标是最新的.net framework,请尝试执行此操作:

private static void GetAccessTokenNonAsync()
{
    var result = GetAccessToken().ConfigureAwait(false).Result;
}

由于异步代码返回某些内容(使用任务签名),因此,如果目标是最新的.net framework,请尝试执行此操作:

private static void GetAccessTokenNonAsync()
{
    var result = GetAccessToken().ConfigureAwait(false).Result;
}
你遇到了麻烦。我在我的博客上描述了细节

理想情况下,您不应该在任何新代码中使用
HttpContext.Current
。在相当长的一段时间内,它一直被认为是一种糟糕的做法,并且在ASP.NET核心中已被完全删除(现在不再使用)

看起来您要做的是将令牌存储在会话状态,并在必要时(异步)创建它。执行此操作的适当方法是使访问器异步:

public static async Task<string> GetAccessTokenAsync()
{
  var result = HttpContext.Current.Session["AccessToken"] as string;
  if (result != null)
    return result;

  ...

  var res = await authContext.AcquireTokenByAuthorizationCodeAsync(...);
  result = res.AccessToken.ToString();
  HttpContext.Current.Session["AccessToken"] = result;
  return result;
}
公共静态异步任务GetAccessTokenAsync() { var result=HttpContext.Current.Session[“AccessToken”]作为字符串; 如果(结果!=null) 返回结果; ... var res=await authContext.AcquireTokenByAuthorizationCodeAsync(…); 结果=res.AccessToken.ToString(); HttpContext.Current.Session[“AccessToken”]=结果; 返回结果; } 您遇到了一个问题。我在我的博客上描述了细节

理想情况下,您不应该在任何新代码中使用
HttpContext.Current
。在相当长的一段时间内,它一直被认为是一种糟糕的做法,并且在ASP.NET核心中已被完全删除(现在不再使用)

看起来您要做的是将令牌存储在会话状态,并在必要时(异步)创建它。执行此操作的适当方法是使访问器异步:

public static async Task<string> GetAccessTokenAsync()
{
  var result = HttpContext.Current.Session["AccessToken"] as string;
  if (result != null)
    return result;

  ...

  var res = await authContext.AcquireTokenByAuthorizationCodeAsync(...);
  result = res.AccessToken.ToString();
  HttpContext.Current.Session["AccessToken"] = result;
  return result;
}
公共静态异步任务GetAccessTokenAsync() { var result=HttpContext.Current.Session[“AccessToken”]作为字符串; 如果(结果!=null) 返回结果; ... var res=await authContext.AcquireTokenByAuthorizationCodeAsync(…); 结果=res.AccessToken.ToString(); HttpContext.Current.Session[“AccessToken”]=结果; 返回结果; }
最终起作用的代码是:

 private static void GetAccessTokenNonAsync()
    {
        var userId = ((ClaimsIdentity)HttpContext.Current.User.Identity).FindFirst("UserId").Value;

        var task = System.Threading.Tasks.Task.Run(async () =>
        {
            return await GetAccessToken( userId);
        });
        task.Wait();
        Current.AccessToken = task.Result.AccessToken;
        Current.AccessTokenExpiresOn = task.Result.ExpiresOn.ToString();
    }

    private static async Task<AuthenticationResult> GetAccessToken(string userId)
    {

        return await System.Threading.Tasks.Task.Factory.StartNew<AuthenticationResult>
        (
            () =>
            {
                string aadInstance = ConfigurationManager.AppSettings["ida:AADInstance"];
                string clientId = ConfigurationManager.AppSettings["ida:ClientId"];
                string clientSecret = ConfigurationManager.AppSettings["ida:ClientSecret"];
                string source = ConfigurationManager.AppSettings["ExchangeOnlineId"];

                var authContext = new AuthenticationContext(aadInstance, false);
                var credentials = new ClientCredential(clientId, clientSecret);
                var res =
                    authContext.AcquireTokenSilentAsync(source, credentials,
                        new UserIdentifier(userId, UserIdentifierType.UniqueId)).Result;
                return res;
            }
        );
    }
private static void GetAccessTokenNonAsync()
{
var userId=((ClaimsIdentity)HttpContext.Current.User.Identity).FindFirst(“userId”).Value;
var task=System.Threading.Tasks.task.Run(异步()=>
{
返回等待GetAccessToken(userId);
});
task.Wait();
Current.AccessToken=task.Result.AccessToken;
Current.AccessTokenExpiresOn=task.Result.ExpiresOn.ToString();
}
私有静态异步任务GetAccessToken(字符串用户ID)
{
返回等待System.Threading.Tasks.Task.Factory.StartNew
(
() =>
{
字符串aadInstance=ConfigurationManager.AppSettings[“ida:aadInstance”];
字符串clientId=ConfigurationManager.AppSettings[“ida:clientId”];
字符串clientSecret=ConfigurationManager.AppSettings[“ida:clientSecret”];
字符串源=ConfigurationManager.AppSettings[“ExchangeOnlineId”];
var authContext=新的AuthenticationContext(aadInstance,false);
var-credentials=新的ClientCredential(clientId,clientSecret);
var res=