私は、この一般的な方法があります:タスクを返す<int>は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
は、あるオブジェクトから別のオブジェクトにth値をコピーするだけです。私はオーバーライドされたの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);
}
EDIT:
これはあなたがSaveChanges()
にSaveChangesWithAuditingAsync
にお電話を待っていないように見えますSaveChangesWithAuditingAsync
private async Task<int> SaveChangesWithAuditingAsync(CancellationToken cancellationToken)
{
return await AuditHelper.SaveChangesWithAuditingAsync(((IObjectContextAdapter)this).ObjectContext, TbHistoryLog, cancellationToken, ChangeTracker);
}
'.Result'は何を説明できますか?可能であれば、あなたはあなたの問題を知っています。あなたができないなら、なぜそれを使うのですか?残念なことに、これは一般的な間違いです。 –
私が知っている限りでは、それはちょうど 'int'であるタスクから結果を抽出する方法です。 –
はい、それはブロック的な方法で行います。だから、あなたはこれらの非同期呼び出しをすべて作って、あなたがちょうど言うことを終わらせます。ちょっと、私の結果を与えるまでブロックしてください。 'public override int SaveChanges()'は 'public override Task SaveChangesAsync()'で、 'SaveChangesWithAuditingAsync'の呼び出しを待つべきです。もちろん、これは待たなければなりません。 –