C# 在任务中使用一次性物品
我正在开发一个Web应用程序来处理大量数据,并用这些数据创建一个.csv文件 到目前为止,还不错,但是,我突然意识到这个过程并不是很快,所以我决定在任务(线程)中完成所有这些事情 像这样:C# 在任务中使用一次性物品,c#,multithreading,task,dispose,C#,Multithreading,Task,Dispose,我正在开发一个Web应用程序来处理大量数据,并用这些数据创建一个.csv文件 到目前为止,还不错,但是,我突然意识到这个过程并不是很快,所以我决定在任务(线程)中完成所有这些事情 像这样: _ = Task.Run(() => { try { LetsGoCrazy(model); } catch (Exception ex) { SaveLog(model, "Error dumbass", ex); } }
_ = Task.Run(() => {
try
{
LetsGoCrazy(model);
}
catch (Exception ex)
{
SaveLog(model, "Error dumbass", ex);
}
});
我的问题是,如何在任务方法中更新数据库(实体框架核心)
因为,它向我显示了这个异常:
System.ObjectDisposedException:'无法访问已处置的对象。此错误的一个常见原因是处理通过依赖项注入解析的上下文,然后在应用程序的其他位置尝试使用相同的上下文实例。如果对上下文调用Dispose(),或将上下文包装到using语句中,则可能会发生这种情况。如果您使用的是依赖项注入,那么应该让依赖项注入容器处理上下文实例
我相信它必须有另一种方法来实现这一点,而不必在任务中重新创建实体框架上下文。您的任务是一个火,忘记您的代码的其他部分一无所知的任务。这意味着应用程序的其余部分不用等待就可以继续运行,释放它认为没有被使用或可能退出的资源。如果你不小心的话,这很容易在控制台应用程序中发生。对于web,您可能会发现控制器超出范围,并且任何资源都会随之消失。从错误的外观来看,情况似乎是这样
您只需等待从task.Run()
返回的任务
try
{
await Task.Run(() => LetsGoCrazy(model));
}
catch (SomeException ex)
{
// ...
}
作品:
到目前为止,还不错,但是,我突然意识到这个过程并不是很快,所以我决定在任务(线程)中完成所有这些事情
在没有看到代码的情况下,简单地将其放在子任务中并不一定会使其运行得更快
依赖注入最佳实践
您应该避免注入I/O资源,例如显式数据库连接;WCF客户端代理;或文件流到客户端代码中。这是因为如果连接出现故障,客户端(比如MVC控制器)将无法重新创建它
相反,您应该插入一个提供者对象,当需要连接时,客户端调用该对象。与其他与DI相关的事物一样,对象创建仍然由DI系统封装,但它允许在发生故障时动态创建和重新创建对象
在您的情况下,如果您的
LetsGoCrazy
需要很长时间(比如>5分钟),您可能需要重新创建数据库连接,因为空闲超时您的任务是一个火,忘记代码中其他部分不知道的任务。您只需等待从task.Run()
返回的任务。在没有看到代码的情况下,简单地将其放在子任务中并不一定能使其运行faster@MichaelRandall哈哈,我确实喜欢你的比喻:)奇怪的比喻,但有道理,兄弟哈哈。我无法让用户等待任务完成。他们会收到一封包含该文件的电子邮件。您可能需要某种消息队列服务来处理LetsGoCrazy
进程外的消息。