簡體   English   中英

退貨任務 <int> 凍結UI?

[英]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內部調用它沒有問題。

SaveChangesasync版本:

   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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM