Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.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 异步void方法未立即返回(EF6)_.net_Entity Framework_Async Await_Entity Framework 6 - Fatal编程技术网

.net 异步void方法未立即返回(EF6)

.net 异步void方法未立即返回(EF6),.net,entity-framework,async-await,entity-framework-6,.net,Entity Framework,Async Await,Entity Framework 6,如果我将Initialise更改为使用wait Task.Run()调用同步this.db.Entities.Load(),则它会立即按预期返回。代码将执行到第一个等待点(对于尚未完成的数据)。请记住,初始化有效地: public class MyClass { MyEntities db = new MyEntities(); public MyClass() { this.Initialise(); // Does not return immedi

如果我将Initialise更改为使用wait Task.Run()调用同步this.db.Entities.Load(),则它会立即按预期返回。

代码将执行到第一个等待点(对于尚未完成的数据)。请记住,
初始化
有效地:

public class MyClass
{
    MyEntities db = new MyEntities();

    public MyClass()
    {
        this.Initialise(); // Does not return immediately. Why?
    }

    private async void Initialise();
    {
        await this.db.Entities.LoadAsync();
    }
}
因此,我们必须得出结论,
LoadAsync
在它产生之前花费了相当长的时间。这完全在API的限制范围内,
await
API只会让事情变得可以等待;它不能保证所有的东西都是非阻塞的。例如,以下内容是完全可以期待的:

var tmp = this.db.Entities.LoadAsync();
await tmp;
静态任务邪恶(){
睡眠(60000);
返回任务.FromResult(4);
}

可能是数据上下文正在加载元数据、加载程序集等—在它知道是否可以生成之前。

我认为延迟是由于第一次使用DbContext实例时实体框架正在预热。LoadAsync()方法可能仅异步执行数据库I/O。预热所花费的时间远远超过我的应用程序中的任何数据库查询。唯一的解决方案是在一个完整的Task.Run()中执行“预热查询”,然后对后续的异步方法使用wait。另一方面,最好避免
Async void
。我的博客上有一些。这个类是一个viewmodel,因此包含视图的其他状态信息,比如按钮是否启用。我需要立即返回构造的对象,否则视图将处于未定义状态。async方法只是填充在构建viewmodel时已经绑定的属性,并且数据异步显示在屏幕上。由于它是一个WPF应用程序,UI线程的同步上下文将捕获异常(与Windows Phone/Windows 8应用商店应用程序不同)。我理解这一点,并重申我的建议,即使用异步初始化方法。与
async void
的唯一区别在于,您可以正确地处理错误(甚至可以通过数据绑定处理异常情况)。WP和Win8应用程序与WPF具有相同的
async void
异常处理-它在UI线程的
SyncContext
上引发。但如果你在那里处理异常,你就是在对局部问题应用全局解决方案。
static Task<int> Evil() {
    Thread.Sleep(60000);
    return Task.FromResult(4);
}