Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/apache-kafka/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 等待任务';迷路';使用dbContext.savechanges()_.net_Vb.net_Entity Framework_Task Parallel Library - Fatal编程技术网

.net 等待任务';迷路';使用dbContext.savechanges()

.net 等待任务';迷路';使用dbContext.savechanges(),.net,vb.net,entity-framework,task-parallel-library,.net,Vb.net,Entity Framework,Task Parallel Library,我在Task.Run()/Task.Factory.StartNew()中偶尔会遇到类似的问题,所以我想我对它的用法一定有一些非常基本的不了解(对于那些喜欢花括号的人,我很抱歉不得不在VB中混淆视听): 我有一个异步方法,代码如下: Try Using context As New ECOSSContext context.Meters.Attach(entity) Await Task.Run(Sub() _

我在Task.Run()/Task.Factory.StartNew()中偶尔会遇到类似的问题,所以我想我对它的用法一定有一些非常基本的不了解(对于那些喜欢花括号的人,我很抱歉不得不在VB中混淆视听):

我有一个异步方法,代码如下:

       Try
        Using context As New ECOSSContext


            context.Meters.Attach(entity)


            Await Task.Run(Sub() _
                               context.SaveChanges() _
                               )

            'ANY CODE HERE NEVER GETS FIRED


        End Using

        Return True

    Catch ex As Exception
        Return False
    End Try
它是从以下同步方法调用的:

Dim result = ModelService.MeterResolution.SaveMeter(data).Result
据我所知,这应该等到方法SaveMeter()返回一个结果。我前面列出的异步方法应该等待Task.Run行,直到它返回,然后继续(因此是wait)。相反,一旦到达等待行,调用堆栈似乎就会退出。SaveChanges()成功,但我无法将此事实通知客户端

我在不同的应用程序中相对频繁地使用TPL,并且没有这些问题,但是我需要使用context.SaveChanges()之类的方法


如有任何建议,我们将不胜感激。我希望我没有误读文档。

问题实际上是由于您使用了
结果。从同步代码调用
async
代码可能非常棘手

我解释这个问题。简言之,默认情况下,在每个
wait
的开头都会保存一个“上下文”,用于恢复该方法

因此,如果在UI或ASP.NET上下文中调用此函数,当
await
完成时,
async
方法将尝试重新进入该上下文以继续执行。不幸的是,使用
Result
(或
Wait
)的代码将阻塞该上下文中的线程,因此
async
方法无法完成

避免这种情况的准则是:

  • 尽可能多地使用
    ConfigureAwait(continueOnCapturedContext:false)
    。这使您的
    async
    方法能够继续执行,而无需重新输入上下文
  • 始终使用
    async
    。使用
    Wait
    代替
    Result
    Wait

  • 除非这是EF6版本之一,否则在多个线程上使用
    DbContext
    通常不是一个好主意。您可能想做的是将整个函数移动到一个异步方法中,确保在单个线程上创建、使用和销毁
    DbContext
    。@CodingGorilla--谢谢您的提示。这一特定指南的理由/权威是什么?请参阅此常见问题解答:@CodingGorilla——谢谢。这不适用,因为我在一个高度分布式的系统中,因此我为每个操作打开和关闭一个上下文。有趣的是——我会深入研究一下你的博客,然后再回复你。你的博客写得非常好。谢谢你的帮助,我很抱歉问了这么多问题!