Mon*_*RPG 1 c# wpf user-interface multithreading task
当我运行下面的代码时,它应该填充ListBox每个DataRow值,但它填充ListBox单DataRow值.
有什么问题,如何解决?这是一个C#4.0 WPF应用程序.
Task.Factory.StartNew(() =>
{
myThread();
});
void myThread()
{
using (DataTable dtTemp = DbConnection.db_Select_DataTable(srQuery))
{
foreach (DataRow drw in dtTemp.Rows)
{
this.Dispatcher.BeginInvoke(new Action(delegate()
{
listBox1.Items.Add(drw["Value"].ToString());
}));
}
}
}
Run Code Online (Sandbox Code Playgroud)
问题是你drw在匿名方法中捕获变量.该变量正在foreach循环中更新,因此,当您在调度程序线程上调用委托时,每次都会获得相同的值.在C#5中,这是可以的(这是一个常见的错误,语言已经改变以避免它)但在C#5之前,你需要在循环中复制变量:
foreach (DataRow drw in dtTemp.Rows)
{
DataRow copy = drw;
this.Dispatcher.BeginInvoke(new Action(delegate()
{
listBox1.Items.Add(copy["Value"].ToString());
}));
}
Run Code Online (Sandbox Code Playgroud)
或者甚至更好,在后台线程中进行所有数据访问:
foreach (DataRow drw in dtTemp.Rows)
{
string item = drw["Value"].ToString();
this.Dispatcher.BeginInvoke(new Action(delegate()
{
listBox1.Items.Add(item);
}));
}
Run Code Online (Sandbox Code Playgroud)
请注意,对C#5的更改仅影响foreach- 而不是for循环.
另请注意,使用lambda表达式而不是匿名方法可以略微缩短代码:
foreach (DataRow drw in dtTemp.Rows)
{
string item = drw["Value"].ToString();
Action action = () => listBox1.Items.Add(item);
this.Dispatcher.BeginInvoke(action);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
107 次 |
| 最近记录: |