实体框架6.1.0 SaveChangesAsync [英] Entity Framework 6.1.0 SaveChangesAsync

查看:259
本文介绍了实体框架6.1.0 SaveChangesAsync的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有EF助手类,它保存更改异步:

I have EF helper class that saves changes async:

public async Task<int> SaveOrUpdateAsync<TEntity>(TEntity entity)
        where TEntity : class, IContextEntity
    {
        if (entity.Id == 0)
            context.Set<TEntity>().Add(entity);
        else
        {
            TEntity dbEntry = context.Set<TEntity>().Find(entity.Id);
            if (dbEntry != null) dbEntry = entity;
        }

        return await context.SaveChangesAsync();
    }

public void Save()
{
Task saveEntit1Async = repository.SaveOrUpdateAsync<Entity1>(entity1);
Task saveEntity2Async = repository.SaveOrUpdateAsync<Entity2>(entity2);
Task saveEntity3Async =  repository.SaveOrUpdateAsync<Entity3>(Entity3);

Task.WaitAll(saveEntit1Async, saveEntity2Async, saveEntity3Async);

string test = "test";
)

呼叫被卡住

Task.WaitAll(saveEntit1Async, saveEntity2Async, saveEntity3Async);

线,永远不会获取

line and never gets to

 string test = "test";

但是,如果我运行它:

But if I run it as:

public void Save()
{
repository.SaveOrUpdateAsync<Entity1>(entity1);
repository.SaveOrUpdateAsync<Entity2>(entity2);
repository.SaveOrUpdateAsync<Entity3>(Entity3);

string test = "test";
)

它工作得很好,所有的改变都被保存并获取到

It works fine, all changes are being saved and it gets to

string test = "test";

为什么

Task.WaitAll(saveEntit1Async, saveEntity2Async, saveEntity3Async);

冻结时的动作,从来没有通过调用code的下一行(字符串测试=测试;)?

Freezes up the operation and never passes call to the next line of code (string test = "test";) ?

推荐答案

我想它了!

下面是一个正在发生的事情的时候,你等待的任务与等待的方法,或直接从任务的结果属性,拍摄效果问题,您阻止主线程
与此同时。当最终任务的方法内部线程池中完成(SaveOrUpdateAsync(TEntity实体)),它会调用连续发布回主线程(因为它从来没有离开过它),因为SynchronizationContext.Current可用并抓获。但这里是一个问题:主线程是由等待的方法阻止,那就是我是如何得到一个僵局

Here is the problem that was happening, when, you wait on the Task with the "Wait" method or take the result directly from the "Result" property of the Task, you block the main thread at the same time. When eventually the Task completes inside that method (SaveOrUpdateAsync(TEntity entity)) in the thread pool, it is going to invoke the continuation to post back to the main thread (as it never left it), because SynchronizationContext.Current is available and captured. But here is a problem: the main thread is blocked by "Wait" method and that is how I was getting a deadlock!

要解决死锁问题,我不得不指定不继续上捕捉上下文context.SaveChangesAsync()。

To fix deadlock issue I had to specify to not to continue on captured context for context.SaveChangesAsync().

public async Task<int> SaveOrUpdateAsync<TEntity>(TEntity entity)
        where TEntity : class, IContextEntity
    {
        if (entity.Id == 0)
            context.Set<TEntity>().Add(entity);
        else
        {
            TEntity dbEntry = context.Set<TEntity>().Find(entity.Id);
            if (dbEntry != null) dbEntry = entity;
        }

        return await context.SaveChangesAsync().ConfigureAwait(continueOnCapturedContext: false);
    }

这篇关于实体框架6.1.0 SaveChangesAsync的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆