1

我在我的 .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() 在 System.Collections.Generic.Dictionary`2.get_Item(TKey key) 在 System.Data.DataView.get_Item(Int32 recordIndex)


我认为我的专栏正在从我的 DataTable 中消失。

谁能告诉我为什么会发生这种情况以及如何阻止这种情况发生?是否有另一种方法我应该初始化我的 DataTable 以便它可以从我的应用程序内的所有方法中使用?

4

1 回答 1

1

首先, aDataTable不是线程安全的,并且您发布的代码不包含任何同步。

您能否详细说明“不包括任何同步”?

您说您有多个线程访问DataTable: 您的CheckUploads方法在后台线程上,并且大概有代码可以在主线程中添加(并可能删除)行。

我建议您将应用程序设计为不需要同步。例如,将 main 的一个克隆传递DataTable给您的后台线程,这样就不会有多个线程访问同一个实例。

我认为我的专栏正在从我的 DataTable 中消失。

我没有看到任何证据:堆栈跟踪似乎表明它未能找到行(System.Data.DataView.get_Item(Int32 recordIndex))而不是列。

来自 ebyrob 的评论:

lock(memTable_CurrentTransfers) { memTable_CurrentTransfers.Rows.Add(filename) } 和其他对 memTable_CurrentTransfers 的访问类似。

您还需要使用相同的锁来访问DataView. 虽然同步很容易出错,所以我支持设计您的应用程序的建议,以便不需要同步。

于 2012-10-08T17:25:56.643 回答