ADO.NET的DataTable / DataRow的线程安全 [英] ADO.NET DataTable/DataRow Thread Safety

查看:456
本文介绍了ADO.NET的DataTable / DataRow的线程安全的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

简介

今天上午,他有一个问题,不一致的结果报告给我的用户(即,列值有时会出来空时,他们不应该)的一些并行执行code,我们提供了一个内部​​的一部分框架。这code在过去运行良好,并没有被篡改最近,但它让我思考下面的代码片断:

A user reported to me this morning that he was having an issue with inconsistent results (namely, column values sometimes coming out null when they should not be) of some parallel execution code that we provide as part of an internal framework. This code has worked fine in the past and has not been tampered with lately, but it got me to thinking about the following snippet:

code样品

lock (ResultTable)
{
    newRow = ResultTable.NewRow();
}

newRow["Key"] = currentKey;
foreach (KeyValuePair<string, object> output in outputs)
{
    object resultValue = output.Value;
    newRow[output.Name] = resultValue != null ? resultValue : DBNull.Value;
}

lock (ResultTable)
{
    ResultTable.Rows.Add(newRow);
}

(不保证了编译,手工编辑,以掩盖proprietery信息。)

(No guarantees that that compiles, hand-edited to mask proprietery information.)

说明

我们已经锁定code等地,在我们的系统中这种层叠式,并能正常工作,但这是级联锁定code,我所遇到的,与ADO .NET交互的第一个实例。大家都知道,框架对象的成员通常不是线程安全的(这是在这种情况下的情况下),但级联锁定应确保我们不会读取和写入ResultTable.Rows兼任。我们是安全的,对吗?

We have this cascading type of locking code other places in our system, and it works fine, but this is the first instance of cascading locking code that I have come across that interacts with ADO .NET. As we all know, members of framework objects are usually not thread safe (which is the case in this situation), but the cascading locking should ensure that we are not reading and writing to ResultTable.Rows concurrently. We are safe, right?

假设

那么,级联锁定code并不能保证我们不会读取或写入ResultTable.Rows 同时,我们分配值在新行的列。如果ADO .NET使用某种缓冲的分配列值是不是线程安全的是什么? - 即使在不同的对象类型涉及(数据表对比的DataRow)

Well, the cascading lock code does not ensure that we are not reading from or writing to ResultTable.Rows at the same time that we are assigning values to columns in the new row. What if ADO .NET uses some kind of buffer for assigning column values that is not thread safe--even when different object types are involved (DataTable vs. DataRow)?

有没有人遇到这样的事情之前?我想我会问这里计算器打我的头这小时年底前:)

Has anyone run into anything like this before? I thought I would ask here at StackOverflow before beating my head against this for hours on end :)

结论

好了,共识似乎是改变级联锁到一个完整的锁已经解决了这个问题。这不是我期待的结果,而是充分锁定版本后,很多,很多,很多的测试还没有产生的问题。

Well, the consensus appears to be that changing the cascading lock to a full lock has resolved the issue. That is not the result that I expected, but the full lock version has not produced the issue after many, many, many tests.

教训:警惕的原料药,你不控制用于级联锁。谁知道在幕后有什么可怎么回事!

The lesson: be wary of cascading locks used on APIs that you do not control. Who knows what may be going on under the covers!

推荐答案

艾伦,

我无法找到你的方法的任何具体问题,不是我的测试是详尽。这里有一些想法,我们坚持(我们所有的应用程序都是螺纹中心):

I could not find any specific problems with your approach, not that my testing was exhaustive. Here are some ideas that we stick with (all of our applications are thread centric):

在可能的情况:

[1]使所有的数据访问完全原子。由于在多线程应用程序的数据共享是各种不可预见的线程交互的好地方。

[1] Make all data access completely atomic. As data sharing in multi-threaded applications is an excellent place for all kinds of unforeseen thread interaction.

[2]避免锁定在一个类型。如果类型是不知道是线程安全的写的包装。

[2] Avoid locking on a type. If the type is not know to be thread safe write a wrapper.

[3]包括结构,其允许快速识别正在访问共享资源的线程。如果系统性能允许,登录上面的调试级别及以下普通操作日志级别信息。

[3] Include structures that allow for the fast identification of threads that are accessing a shared resource. If system performance allows, log this information above the debug level and below usual operation log levels.

[4]任何code,包括系统* et.al,没有明确地内部记录为线程安全测试是不是线程安全的。传闻和他人的口头话不算数。测试它,把它写下来。

[4] Any code, including System.* et.al, not explicitly documented internally as Thread Safe Tested is not Thread Safe. Hearsay and the verbal word of others does not count. Test it and write it down.

希望这是有一定价值。

这篇关于ADO.NET的DataTable / DataRow的线程安全的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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