- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
此问题与此处另一篇文章中的评论相关:Cancelling an Entity Framework Query
为了清楚起见,我将从那里重现代码示例:
var thread = new Thread((param) =>
{
var currentString = param as string;
if (currentString == null)
{
// TODO OMG exception
throw new Exception();
}
AdventureWorks2008R2Entities entities = null;
try // Don't use using because it can cause race condition
{
entities = new AdventureWorks2008R2Entities();
ObjectQuery<Person> query = entities.People
.Include("Password")
.Include("PersonPhone")
.Include("EmailAddress")
.Include("BusinessEntity")
.Include("BusinessEntityContact");
// Improves performance of readonly query where
// objects do not have to be tracked by context
// Edit: But it doesn't work for this query because of includes
// query.MergeOption = MergeOption.NoTracking;
foreach (var record in query
.Where(p => p.LastName.StartsWith(currentString)))
{
// TODO fill some buffer and invoke UI update
}
}
finally
{
if (entities != null)
{
entities.Dispose();
}
}
});
thread.Start("P");
// Just for test
Thread.Sleep(500);
thread.Abort();
我无法理解下面的评论
Don't use using because it can cause race condition
entities
是一个局部变量,如果代码在另一个线程上重新输入,则不会共享,并且在同一个线程中它看起来非常安全(并且实际上等同于给定的代码) 以通常的方式将其分配到“using”语句中,而不是使用 try/finally 手动执行操作。谁能赐教一下?
最佳答案
是的,using 语句中可能存在竞争。 C# 编译器转换
using (var obj = new Foo()) {
// statements
}
到:
var obj = new Foo();
try {
// statements
}
finally {
if (obj != null) obj.Dispose();
}
当线程在 obj 赋值语句和 try block 之间中止时,就会发生竞争。赔率极小但不为零。发生这种情况时,该对象不会被处置。请注意他是如何通过将赋值移动到 try block 中来重写该代码的,这样就不会发生这种竞争。当竞争发生时,实际上没有什么根本性的错误,不需要处理对象。
必须在稍微提高线程中止效率和手动编写 using 语句之间做出选择,您应该首先选择不要养成使用 Thread.Abort() 的习惯。我不建议实际这样做,using 语句有额外的安全措施来确保事故不会发生,即使在使用语句。添加 catch 子句也不太容易发生事故。 using 语句的存在是为了减少出现错误的可能性,请始终使用它。
关于这个问题的一点点思考,答案很受欢迎,还有另一个常见的 C# 语句遭受完全相同的竞争。它看起来像这样:
lock (obj) {
// statements
}
翻译成:
Monitor.Enter(obj);
// <=== Eeeek!
try {
// statements
}
finally {
Monitor.Exit(obj);
}
完全相同的场景,线程中止可以在 Enter() 调用之后和进入 try block 之前触发。这阻止了 Exit() 调用。这 方式 比没有进行的 Dispose() 调用更糟糕,当然,这几乎肯定会导致死锁。该问题特定于 x64 抖动,此 Joe Duffy blog post 中详细描述了肮脏的细节.
很难可靠地修复这个问题,将 Enter() 调用移动到 try block 中无法解决问题。您无法确定是否进行了 Enter 调用,因此您无法在不触发异常的情况下可靠地调用 Exit() 方法。 Duffy 所说的 Monitor.ReliableEnter() 方法最终实现了。 Monitor 的 .NET 4 版本有一个 TryEnter() 重载,它带有一个 ref bool lockTaken
参数。现在您知道可以调用 Exit() 了。
好吧,可怕的东西会在你不注意的时候突然出现。编写可安全中断的代码是困难。明智的做法是永远不要假设不是您编写的代码已经处理了所有这些问题。测试此类代码非常困难,因为比赛非常罕见。你永远无法确定。
关于c# - 为什么 try/finally 而不是 "using"语句有助于避免竞争条件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14830534/
我在优化 JOIN 以使用复合索引时遇到问题。我的查询是: SELECT p1.id, p1.category_id, p1.tag_id, i.rating FROM products p1
我有一个简单的 SQL 查询,我正在尝试对其进行优化以删除“使用位置;使用临时;使用文件排序”。 这是表格: CREATE TABLE `special_offers` ( `so_id` int
我有一个具有以下结构的应用程序表 app_id VARCHAR(32) NOT NULL, dormant VARCHAR(6) NOT NULL, user_id INT(10) NOT NULL
此查询的正确索引是什么。 我尝试为此查询提供不同的索引组合,但它仍在使用临时文件、文件排序等。 总表数据 - 7,60,346 产品= '连衣裙' - 总行数 = 122 554 CREATE TAB
为什么额外的是“使用where;使用索引”而不是“使用索引”。 CREATE TABLE `pre_count` ( `count_id`
我有一个包含大量记录的数据库,当我使用以下 SQL 加载页面时,速度非常慢。 SELECT goal.title, max(updates.date_updated) as update_sort F
我想知道 Using index condition 和 Using where 之间的区别;使用索引。我认为这两种方法都使用索引来获取第一个结果记录集,并使用 WHERE 条件进行过滤。 Q1。有什
I am using TypeScript 5.2 version, I have following setup:我使用的是TypeScript 5.2版本,我有以下设置: { "
I am using TypeScript 5.2 version, I have following setup:我使用的是TypeScript 5.2版本,我有以下设置: { "
I am using TypeScript 5.2 version, I have following setup:我使用的是TypeScript 5.2版本,我有以下设置: { "
mysql Ver 14.14 Distrib 5.1.58,用于使用 readline 5.1 的 redhat-linux-gnu (x86_64) 我正在接手一个旧项目。我被要求加快速度。我通过
在过去 10 多年左右的时间里,我一直打开数据库 (mysql) 的连接并保持打开状态,直到应用程序关闭。所有查询都在连接上执行。 现在,当我在 Servicestack 网页上看到示例时,我总是看到
我使用 MySQL 为我的站点构建了一个自定义论坛。列表页面本质上是一个包含以下列的表格:主题、上次更新和# Replies。 数据库表有以下列: id name body date topic_id
在mysql中解释的额外字段中你可以得到: 使用索引 使用where;使用索引 两者有什么区别? 为了更好地解释我的问题,我将使用下表: CREATE TABLE `test` ( `id` bi
我经常看到人们在其Haxe代码中使用关键字using。它似乎在import语句之后。 例如,我发现这是一个代码片段: import haxe.macro.Context; import haxe.ma
这个问题在这里已经有了答案: "reduce" or "apply" using logical functions in Clojure (2 个答案) 关闭 8 年前。 “and”似乎是一个宏,
这个问题在这里已经有了答案: "reduce" or "apply" using logical functions in Clojure (2 个答案) 关闭 8 年前。 “and”似乎是一个宏,
我正在考虑在我的应用程序中使用注册表模式来存储指向某些应用程序窗口和 Pane 的弱指针。应用程序的一般结构如下所示。 该应用程序有一个 MainFrame 顶层窗口,其中有几个子 Pane 。可以有
奇怪的是:。似乎a是b或多或少被定义为id(A)==id(B)。用这种方式制造错误很容易:。有些名字出人意料地出现在Else块中。解决方法很简单,我们应该使用ext==‘.mp3’,但是如果ext表面
我遇到了一个我似乎无法解决的 MySQL 问题。为了能够快速执行用于报告目的的 GROUP BY 查询,我已经将几个表非规范化为以下内容(该表由其他表上的触发器维护,我已经同意了与此): DROP T
我是一名优秀的程序员,十分优秀!