我对新的异步/等待的东西还很陌生。但是,我有以下类(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,...);
}
}
}
最佳答案
那是因为在调用链的更高处,有人正在处理您的插件对象,但实际上并没有完成异步操作。使用async void
正在执行“即发即弃”操作。您实际上并没有在await
上使用Process
,因此任何调用它的人都假定它完成了并处理了您的对象。
将您的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/