【问题标题】:How to prevent multiple threads manipulating instance of referenced object?如何防止多个线程操作引用对象的实例?
【发布时间】:2015-01-10 05:06:40
【问题描述】:

我目前正在使用 .NET Framework 使用 C# 设计和编写一个应用程序,该应用程序从文件中导入一些数据。导入数据后,它可以绑定到一个或多个 Windows 窗体中的 DataGridView,以允许用户在将数据导出回文件之前对其进行操作。

我希望我的表单在导出过程中保持响应,并且可以取消导出操作。我打算创建一个 BackgroundWorker 并设置 DoWork 处理程序来执行导出操作,因此导出操作是在后台线程中执行的。我这样做是为了允许在表单中更新操作的进度,以及其他原因。我打算将数据传递给工作人员以允许它进行导出。

然而,我担心一旦我启动了 worker 并且我的 worker 正在执行导出操作,该操作可能仍绑定到一个或多个 DataGridViews,我的数据会被多个线程访问,并且用户可以更新导出时使用表单的数据。

有谁知道我可以如何防止表单在导出数据时引用和弄乱数据?

我还没有编写任何代码,但我在下面编写了一些代码,希望能传达我的想法,我敢肯定这是一种可怕的方式。

class Data : List<string>, MyInterface
{

}

class Form
{

   Data data;

  void SetData(Data data)
  {
      this.data = data;
      dataGridView.DataSource = data;
  }

  void ButtonClickHandler()
  {
     //Create a BackgroundWorker with the DoWork handler set up to
     //save/exports each item in data to a file.

  }

}

【问题讨论】:

  • 嗯,这基本上是多线程设计作为一门学科的整个问题陈述。因此,我建议查找各种教程(来自 MS 或其他任何地方),然后再回来。
  • @NathanTuggy:嗯,我得出的结论是互斥锁无济于事。我考虑了一个信号量,或者某种方式来保持对引用数据的计数,然后在引用计数不为零时阻止导出。但后来我看不到任何明智的方法来确保引用计数无论如何都是准确的。
  • 如何在导出过程中禁用网格编辑功能(但仍允许用户浏览和查看)并在导出例程完成后重新启用该功能?
  • @Tien Dinh:我考虑过。我不想相信表格。我唯一的另一个想法是在导出时强制表单使用列表的只读版本,在导出后重新提供非只读版本。
  • 实际上有一千种方法可以解决这个问题 - 一种方法是制作数据副本并将该副本传递给导出例程。然后,通过表单进行的任何更改都不会更改正在导出的副本。

标签: c# .net multithreading winforms datagridview


【解决方案1】:

如果您不希望用户修改您尝试导出的数据,您有两个可行的选择:

  1. 在导出过程中禁用允许修改数据的 UI 部分(例如,将 DataGridView 单元格设为只读),或
  2. 在导出前制作数据副本,并导出副本,而不是用户能够编辑的实时数据。

其他同步技术会阻塞 UI 线程,这当然是一个巨大的“禁忌”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-29
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    • 2014-02-11
    相关资源
    最近更新 更多