[英]ObjectDisposedException when trying to access Thread.CurrentPrincipal with async method
我對新的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進行異步調用。 當我從該調用返回並嘗試調用base.LogEvent()時,我得到一個ObjectDisposedException,指出“Safe Handle已被關閉”。
我知道當等待完成時會發生一些事情,必須運行該方法的其余代碼。 也許它在其他一些線程或上下文中運行? 如果是這種情況,如何在寫入日志時獲取當前用戶?
感謝您對此的幫助。
編輯根據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,...);
}
}
}
當我從該調用返回並嘗試調用base.LogEvent()時,我得到一個ObjectDisposedException,指出“Safe Handle已被關閉”。
那是因為在調用鏈的某個地方,有人正在處理你的插件對象,而這個對象還沒有真正完成異步操作。 使用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
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.