【发布时间】:2014-12-03 11:55:37
【问题描述】:
我正在使用 .NET 4.0 用 C# 开发一个 MDI 应用程序。
每个 MDI 子项都将是一个带有选项卡的表单,其中包含带有 DataGridView 的 GroupBoxes。
我实现了一个用于管理线程的类。
这是我的ThreadManager 类中的StartNewThread 方法
public string StartNewThread(ThreadStart threadMethod, string threadName)
{
try
{
Thread thread = new Thread(() => threadMethod());
thread.Name = threadName + " (" + _threadCount++.ToString("D4") + ")";
thread.Start();
_threadList.Add(thread.Name, thread);
return thread.Name;
}
catch (Exception ex)
{
//Log and manage exceptions
}
return null;
}
为了创建 DataGridViews,我使用了 Oracle Developer Tools for VS 库中的一些向导组件。因此,在创建了 DataSource 和 DataSet 之后,我使用从 DataSource 树中拖放来拖动表格并自动创建 DataGridViews。
这是实际的工作代码,在子窗体后面,自动创建。
public partial class ScuoleNauticheForm : Form
{
public ScuoleNauticheForm()
{
InitializeComponent();
}
private void ScuoleNauticheForm_Load(object sender, EventArgs e)
{
// TODO: This line of code loads data into the 'dEVRAC_NauticheDataSet.PERSONALE' table. You can move, or remove it, as needed.
this.PersonaleTableAdapter.Fill(this.DEVRAC_NauticheDataSet.PERSONALE);
// TODO: This line of code loads data into the 'dEVRAC_NauticheDataSet.NATANTI' table. You can move, or remove it, as needed.
this.NatantiTableAdapter.Fill(this.DEVRAC_NauticheDataSet.NATANTI);
// TODO: This line of code loads data into the 'dEVRAC_NauticheDataSet.SCUOLE' table. You can move, or remove it, as needed.
this.ScuoleTableAdapter.Fill(this.DEVRAC_NauticheDataSet.SCUOLE);
}
}
我现在要做的是管理所有在分离线程上的加载/查询/插入/更新/删除操作。现在我尝试创建一个新线程来加载数据。
这是我尝试过的。
public partial class ScuoleNauticheForm : Form
{
private readonly ThreadManager _threadManager;
public ScuoleNauticheForm()
{
InitializeComponent();
_threadManager = ThreadManager.GetInstance();
}
private void ScuoleNauticheForm_Load(object sender, EventArgs e)
{
_threadManager.StartNewThread(LoadData, "LoadData");
}
#region DataBind
private void LoadData()
{
// TODO: This line of code loads data into the 'dEVRAC_NauticheDataSet.PERSONALE' table. You can move, or remove it, as needed.
this.PersonaleTableAdapter.Fill(this.DEVRAC_NauticheDataSet.PERSONALE);
// TODO: This line of code loads data into the 'dEVRAC_NauticheDataSet.NATANTI' table. You can move, or remove it, as needed.
this.NatantiTableAdapter.Fill(this.DEVRAC_NauticheDataSet.NATANTI);
// TODO: This line of code loads data into the 'dEVRAC_NauticheDataSet.SCUOLE' table. You can move, or remove it, as needed.
this.ScuoleTableAdapter.Fill(this.DEVRAC_NauticheDataSet.SCUOLE);
}
#endregion
}
它只适用于一半...没有错误或异常,但如果我以这种方式加载数据,使用不同的Thread,DataGridviews 不会更新,打开表单时我看不到任何数据,即使我移动或调整它的大小。否则,使用自动生成的代码,可以正确填充 DataGridView。
但是,由于向导还在表单中添加了一个导航栏来浏览记录,我注意到它可以工作,因为它计算了正确的记录数,我可以使用箭头(第一个、上一个、下一个、最后一个)来移动记录。
这是显示我的表单的图像。 查看显示正确总记录数 (14) 并允许我浏览它们的导航栏。
我需要使用delegates吗?如果是这样,我认为这将是一团糟......我应该创建多少 delegates 以及这些方法?还是有其他解决方案?
-- 更新 1--
我知道 UI 线程是由 .NET 自动管理的,因此程序员不需要使用代码来管理它们。那么,是否应该是与管理中内置的.NET UI 线程同步的问题呢?可能我Form.Load()发起的线程干扰了.NET管理的UI线程?
-- 更新 2 --
我尝试实现faby提出的解决方案。我用Task 逻辑替换了我的Thread 逻辑。应用程序的行为是相同的,所以使用Thread 的所有内容现在也可以使用Task。 但问题仍然存在。由于我使用的是 .NET 4.0 而不是 .NET 4.5,因此我无法使用 async 和 await。所以我不知道用这种方法 UI 是否能正常工作。
还有其他适用于 .NET 4.0 的建议吗?
【问题讨论】:
-
看看我更新的答案,有诀窍!
标签: c# multithreading oracle user-interface datagridview