尝试使用异步方法访问Thread.CurrentPrincipal时出现ObjectDisposedException

本文关键字:CurrentPrincipal ObjectDisposedException Thread 访问 异步方法 | 更新日期: 2023-09-27 17:51:20

我对新的async/await内容相当陌生。然而,我有以下类别:

public abstract class PluginBase
{
   //Using EF to store log info to database
   private EFContext _context = new EFContext();
   private int Id = 1;
   protected void LogEvent(string event, string details)
   {
       _context.LogEvents.Add(new LogItem(){
          PluginId = this.Id,
          Event = event,
          Details = details,
          User = Thread.CurrentPrincipal.Identity.Name
       });
   }
 }
public class Plugin : PluginBase
{
   public void Process()
   {
      CallWebService();
   }
   public async void CallWebService()
   {
       using(var http = new HttpClient())
       {
          ...
          var result = await http.PostAsync(memberURI, new StringContent(content, Encoding.UTF8,"application/json"));
          if(result.IsSuccessStatusCode)
             _status = "Success";
          else
             _status = "Fail";
          LogEvent("Service Call - " + _status,...);
       }
}

所以,这个想法是Plugin.Process被调用。它反过来调用CallWebService((。CallWebService对http进行异步调用。PostAsync。当我从那个电话回来并尝试呼叫基地时。LogEvent((,我得到一个ObjectDisposedException,声明"安全句柄已关闭"。

我知道当awaitable完成时,必须运行该方法的其余代码。也许它是在其他线程或上下文中运行的?如果是这种情况,在写入日志时如何获取当前用户?

谢谢你在这方面的帮助。

编辑根据尤瓦尔的回答,我做了以下更改,看起来效果不错。

public void Process()
{
    var task = CallWebService();
    task.Wait();
}
public async Task CallWebService(List<Member> members)
{
    using(var http = new HttpClient())
    {
       ...
       using(var result = await http.PostAsync(memberURI, new StringContent content, Encoding.UTF8, "application/json")))
       {
          if(result.IsSuccessStatusCode)
             _status = "Success";
          else
             _status = "Fail";
          LogEvent("Service Call - " + _status,...);
        }
    }
 }

尝试使用异步方法访问Thread.CurrentPrincipal时出现ObjectDisposedException

当我从那个电话回来并尝试呼叫基地时。LogEvent((,我得到一个ObjectDisposedException声明"安全句柄已关闭"。

这是因为在调用链的更高层,有人正在处理你的插件对象,而它还没有真正完成异步操作。使用async void就是在做一个"点火并忘记"的操作。实际上Process上没有await,因此任何调用它的人都认为它已经完成并处理了您的对象。

async void方法更改为async Taskawait方法为

public Task ProcessAsync()
{
    return CallWebServiceAsync();
}
public async Task CallWebServiceAsync()
{
   using (var http = new HttpClient())
   {
      var result = await http.PostAsync(memberURI, 
                                        new StringContent(content,
                                                          Encoding.UTF8,
                                                          "application/json"));
      if (result.IsSuccessStatusCode)
         _status = "Success";
      else
         _status = "Fail";
      LogEvent("Service Call - " + _status,...);
   }
}

请注意,您还需要将await ProcessAsync放在调用堆栈的较高位置。

相关文章:
  • 没有找到相关文章