DataTable快速填充
DataTable rapid population
美好的一天!
我有一个多线程应用程序,其目的通常是处理一个非常快速填充的消息队列。消息由一个线程添加到队列,另一个线程处理它们。
在处理线程中,一些消息必须显示在网格中。 Grid 的DataSource 是DataTable。处理线程与 DataTable 一起工作(在每个消息处理上;NID、SID、BID - 是 1 条消息的一部分):
Lockers[5].WaitOne();
Continue = true;
for (int i = 0; i <= mDataSource.Tables["Stations"].Rows.Count - 1; i++)
{
DataRow Current = mDataSource.Tables["Stations"].Rows[i];
if ((ushort)Current["SID"] == SID &&
(ushort)Current["NID"] == NID &&
(ushort)Current["BID"] == BID)
{
Continue = false;
break;
}
}
if (Continue &&)
{
SyncContext.Post(x =>
{
mDataSource.Tables["Stations"].BeginLoadData();
mDataSource.Tables["Stations"].Rows.Add(
(fbn + 1) * 10 + 1 + dn,
DeviceList[fbn].Main.Receivers[dn].Channel,
DeviceList[fbn].Main.Receivers[dn].Pilot, SID, NID, BID,
DeviceList[fbn].Receivers[dn].MCC, Latitude, Longitude);
mDataSource.Tables["Stations"].EndLoadData();
},
null);
}
Lockers[5].ReleaseMutex();
Lockers[5] - Mutex 对象,mDataSource - DataSet 对象。 SynContext - 是主应用程序表单的同步上下文。正如我上面所说的,消息队列的填充速度非常快,因此这段代码在运行时的 1 秒内触发了大约 500 次。在消息队列中可能会重复,所以我不能显示它们。问题是在消息处理线程的几次第一次迭代中我得到 mDataSource.Tables["Stations"].Rows.Count = 0,因此我的 Continue 变量 = true 并且我有一个重复table。在接下来的迭代中,我还在日志中看到在 table 中添加了行,但计数可能仍为 2(但在日志中添加了 17 行)。为什么会这样?
我尝试更改 lock(){} 运算符上的 Mutex 对象。这对我没有帮助。我尝试更改 BindingList 上的 DataTable。这对我没有帮助。我可以通过创建全局变量 private readonly int[] LastAddedStation = new int[3]; 来降低 table 中的重复次数;并在 if 块中添加这样的表达式 (if (Continue){}): LastAddedStation[0] != SID || LastAddedStation[1] != NID || LastAddedStation[2] != 出价。它帮助我降低了 table 中的重复次数,但在我看来,它是 "smells"。有什么明确的方法可以帮助我解决这个问题吗?
我做错了什么?使用 DataTables 的高负载最佳实践是什么?
P.S。抱歉我的英语不好,我不是母语人士。
主要是在这里回答- What is the difference between SynchronizationContext.Send and SynchronizationContext.Post? .
Post 方法在异步模式下工作 - "drop off and continue"。所以似乎 post 方法中的下一次迭代代码尚未完成。
我选择添加一个单独的计数器来计算添加的行并使用 DataTable.Count 检查它。
美好的一天!
我有一个多线程应用程序,其目的通常是处理一个非常快速填充的消息队列。消息由一个线程添加到队列,另一个线程处理它们。
在处理线程中,一些消息必须显示在网格中。 Grid 的DataSource 是DataTable。处理线程与 DataTable 一起工作(在每个消息处理上;NID、SID、BID - 是 1 条消息的一部分):
Lockers[5].WaitOne();
Continue = true;
for (int i = 0; i <= mDataSource.Tables["Stations"].Rows.Count - 1; i++)
{
DataRow Current = mDataSource.Tables["Stations"].Rows[i];
if ((ushort)Current["SID"] == SID &&
(ushort)Current["NID"] == NID &&
(ushort)Current["BID"] == BID)
{
Continue = false;
break;
}
}
if (Continue &&)
{
SyncContext.Post(x =>
{
mDataSource.Tables["Stations"].BeginLoadData();
mDataSource.Tables["Stations"].Rows.Add(
(fbn + 1) * 10 + 1 + dn,
DeviceList[fbn].Main.Receivers[dn].Channel,
DeviceList[fbn].Main.Receivers[dn].Pilot, SID, NID, BID,
DeviceList[fbn].Receivers[dn].MCC, Latitude, Longitude);
mDataSource.Tables["Stations"].EndLoadData();
},
null);
}
Lockers[5].ReleaseMutex();
Lockers[5] - Mutex 对象,mDataSource - DataSet 对象。 SynContext - 是主应用程序表单的同步上下文。正如我上面所说的,消息队列的填充速度非常快,因此这段代码在运行时的 1 秒内触发了大约 500 次。在消息队列中可能会重复,所以我不能显示它们。问题是在消息处理线程的几次第一次迭代中我得到 mDataSource.Tables["Stations"].Rows.Count = 0,因此我的 Continue 变量 = true 并且我有一个重复table。在接下来的迭代中,我还在日志中看到在 table 中添加了行,但计数可能仍为 2(但在日志中添加了 17 行)。为什么会这样?
我尝试更改 lock(){} 运算符上的 Mutex 对象。这对我没有帮助。我尝试更改 BindingList 上的 DataTable。这对我没有帮助。我可以通过创建全局变量 private readonly int[] LastAddedStation = new int[3]; 来降低 table 中的重复次数;并在 if 块中添加这样的表达式 (if (Continue){}): LastAddedStation[0] != SID || LastAddedStation[1] != NID || LastAddedStation[2] != 出价。它帮助我降低了 table 中的重复次数,但在我看来,它是 "smells"。有什么明确的方法可以帮助我解决这个问题吗?
我做错了什么?使用 DataTables 的高负载最佳实践是什么?
P.S。抱歉我的英语不好,我不是母语人士。
主要是在这里回答- What is the difference between SynchronizationContext.Send and SynchronizationContext.Post? .
Post 方法在异步模式下工作 - "drop off and continue"。所以似乎 post 方法中的下一次迭代代码尚未完成。
我选择添加一个单独的计数器来计算添加的行并使用 DataTable.Count 检查它。