gpt4 book ai didi

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

转载 作者:太空狗 更新时间:2023-10-30 01:34:28 24 4
gpt4 key购买 nike

我对新的 async/await 东西还很陌生。但是,我有以下类(class):

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 进行异步调用。当我从该调用返回并尝试调用 base.LogEvent() 时,我收到一个 ObjectDisposedException,指出“安全句柄已关闭”。

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

感谢您对此的帮助。

编辑根据 Yuval 的回答,我进行了以下更改,它似乎工作正常。

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,...);
}
}
}

最佳答案

When I return from that call and try to call base.LogEvent(), I get an ObjectDisposedException stating that "Safe Handle has been Closed".

那是因为在调用链的较高位置,有人正在处置您的插件对象,而该对象尚未真正完成异步操作。使用 async void 是在执行“即发即弃”操作。您实际上并没有在 Processawait,因此调用它的任何人都假定它已完成并处理您的对象。

将您的async void方法更改为async Task,然后await它:

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 位于调用堆栈更高层的位置。

关于c# - 尝试使用异步方法访问 Thread.CurrentPrincipal 时出现 ObjectDisposedException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30577518/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com