我在.Net 3.5应用程序中使用DataTable来存储1列,其中包含一些包含文件名的记录。
以下是我的初始化DataTable的方式和位置的代码:
public partial class MainForm : Form
{
DataTable memTable_CurrentTransfers = new DataTable();
private void MainForm_Load(object sender, EventArgs e)
{
memTable_CurrentTransfers.Columns.Add("fileName", typeof (string));
以下是我在应用程序的另一种方法中将文件名添加到DataTable的方法:
memTable_CurrentTransfers.Rows.Add(fileName);
每30分钟,我启动一个执行此代码的线程:
public void CheckUploads()
{
DataView view2 = memTable_CurrentTransfers.DefaultView;
for (int i = 0; i < view2.Count; i++)
{
string tmpString = view2[i][0].ToString();
一切都很好,但在我的应用程序运行一段时间后,我的用户开始在CheckUploads()方法中出现此错误
字典中没有给定的密钥。在 System.ThrowHelper.ThrowKeyNotFoundException()at System.Collections.Generic.Dictionary`2.get_Item(TKey key)at System.Data.DataView.get_Item(Int32 recordIndex)
我认为我的专栏正在从我的DataTable中消失。
可以请任何人告诉我为什么会发生这种情况以及如何阻止这种情况发生?还有另一种方法我应该初始化我的DataTable,以便它可以从我的应用程序内部的所有方法中获得吗?
答案 0 :(得分:1)
首先,DataTable
不是线程安全的,您发布的代码不包含任何同步。
你能详细说明&#34;不包括任何同步&#34;?
你说你有多个线程访问DataTable
:你的CheckUploads
方法是在后台线程上,并且可能有代码在主线程中添加(并可能删除)行。
我建议您设计应用程序,以便不需要同步。例如,将主DataTable
的克隆传递给后台线程,这样就不会有多个线程访问同一个实例。
我认为我的专栏正在从我的DataTable中消失。
我没有看到任何证据:堆栈跟踪似乎表明它没有找到一行(System.Data.DataView.get_Item(Int32 recordIndex)
)而不是一列。
来自ebyrob的评论:
lock(memTable_CurrentTransfers){memTable_CurrentTransfers.Rows.Add(filename)}和类似于对memTable_CurrentTransfers的每次其他访问。
您还需要对DataView
的任何访问使用相同的锁定。虽然很容易让同步变得错误,但我仍然坚持设计您的应用的建议,以便不需要同步。