[英]Returning Task<int> freezes the UI?
我有這種通用方法:
public static async Task<int> SaveChangesWithAuditingAsync<TLogType>(ObjectContext dbContext, DbSet<TLogType> logsSet, CancellationToken cancellationToken, DbChangeTracker changeTracker)
where TLogType : class, new()
{
ObjectContext context = ((IObjectContextAdapter)dbContext).ObjectContext;
await context.SaveChangesAsync(SaveOptions.DetectChangesBeforeSave, cancellationToken).ConfigureAwait(false);
var audits = new List<TLogType>();
foreach (var entry in changeTracker.Entries().Where(o => o.State == EntityState.Modified || o.State == EntityState.Added).ToList())
{
var changeType = entry.State.ToString();
Type entityType = GetEntityType(entry);
string tableName = GetTableName(context, entityType);
var audit = new TbCommonHistoryLog
{
ObjectJson = GetEntityAsJson(entry),
TableName = tableName,
};
TLogType t = new TLogType();
t.ChargeFrom(audit);
audits.Add(t);
}
logsSet.AddRange(audits);
int result = 0;
try
{
result = await context.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
return result;
}
catch (Exception ex)
{
var m = ex.Message;
return result;
}
}
我創建它的原因是因為我有多個DbContext
,並且需要具有相同的代碼,所以我創建了AuditHelper
類來保存此方法。 所有DbContext
■找相同的表結構(但以不同的名稱),這是TLogType
。 ChargeFrom
只是將值從一個對象復制到另一個。
問題是,當我從覆蓋的SaveChanges()方法調用它時,UI凍結:
public override int SaveChanges()
{
return SaveChangesWithAuditingAsync(CancellationToken.None).Result;
}
我注意到在SaveChanges
內部調用它沒有問題。
SaveChanges
的async
版本:
public override Task<int> SaveChangesAsync()
{
return SaveChangesWithAuditingAsync(CancellationToken.None);
}
public override Task<int> SaveChangesAsync(CancellationToken cancellationToken)
{
return SaveChangesWithAuditingAsync(cancellationToken);
}
編輯:
這是SaveChangesWithAuditingAsync
private async Task<int> SaveChangesWithAuditingAsync(CancellationToken cancellationToken)
{
return await AuditHelper.SaveChangesWithAuditingAsync(((IObjectContextAdapter)this).ObjectContext, TbHistoryLog, cancellationToken, ChangeTracker);
}
當我從重寫的SaveChanges()方法調用它時,UI凍結
是的, 對Result
的調用導致死鎖 。 理想情況下,避免這種情況的最佳方法是根本不調用SaveChanges
而是使用SaveChangesAsync
,並從SaveChanges
拋出異常,表明不支持同步API。
如果這是不可接受的,那么您可以考慮使用我在Brownfield異步代碼上的文章中的一種技巧 。 請注意,每種hack都有其自身的缺點,並且沒有適用於每種情況的hack 。
不要使用.Result,它會等待結果在調用線程上可用,從而阻止進一步執行。
似乎您沒有在等待SaveChanges()
對SaveChangesWithAuditingAsync
的調用-這不會給您帶來任何好處。 到處添加可能會很痛苦,但是如果您不希望崩潰或掛起,則需要這樣做。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.