我遇到了一个问题,即集合中的第一项是响应更新但没有其他(40项)。我已经浏览了网络寻找答案,但不幸的是,几天后我仍然无处可去。
启动检测循环的线程的调用代码:
_detectionThread = new Thread(() => _x.StartDetection());
_detectionThread.Start();
我在我的一个帮助程序类中得到了以下代码,它只是轮询,当检测到某些东西时,通过一个事件调用View-Model:
public event EventHandler SomethingIsDetected;
private void OnSomethingDetected()
{
if (SomethingIsDetected!= null)
{
SomethingIsDetected(this, new EventArgs());
}
}
检测循环代码:
var startCheckTime = DateTime.Now;
var nextCheck = startCheckTime.AddSeconds(PollingInterval.TotalSeconds);
while (_performDetection)
{
startCheckTime = DateTime.Now;
if (startCheckTime >= nextCheck)
{
nextCheck = startCheckTime.AddSeconds(PollingInterval.TotalSeconds);
{
var detectionTask = Task.Factory.StartNew(() => IsXConnected());
IsXPresent = detectionTask.Result;
Thread.Sleep(TimeSpan.FromSeconds(1));
if (IsXPresent)
{
Application.Current.Dispatcher.Invoke(new Action(OnSomethingDetected));
}
}
}
Thread.Sleep(10);
}
更新项目的代码。 View绑定到此处的属性(尤其是CurrentItem)。 Items是一个ObservableCollection
foreach (var item in Items) //loop through 40 items
{
//do some operation then set the current item
Application.Current.Dispatcher.Invoke(new Action(() => CurrentItem = item));
}
当我单步执行时(在调试转换器的帮助下),我注意到该项目是第一次使用。其余的只是循环。我已经使用DependencyProperty设置了属性CurrentItem。
我尝试使用CheckAccess来使用Delegate和udpate属性,但这也没有帮助。
欢迎任何帮助,谢谢!
答案 0 :(得分:3)
您的问题与多线程无关,它必须与闭包如何捕获您上一个代码段中的变量。你lamba都共享相同的变量,即只有一个item
变量。由于你的lamda在循环结束后运行item
将始终设置为Items集合中的最后一项。 (虽然它们可以与任何项目一起运行,具体取决于何时运行)
编译器将转换:
foreach (var item in Items) //loop through 40 items
{
//do some operation then set the current item
Application.Current.Dispatcher.Invoke(new Action(() => CurrentItem = item));
}
与道德等同于此:
class closuseCapture {
private ItemType itemCapture;
public void Loop() {
foreach (var item in Items) //loop through 40 items
{
itemCapture = item;
//do some operation then set the current item
Application.Current.Dispatcher.Invoke(new Action(ActionMethod));
}
}
public void ActionMethod() {
CurrentItem = itemCapture;
}
修复是在循环中声明一个变量,这样循环的每个交互都会得到它自己的项目副本:
foreach (var item in Items) //loop through 40 items
{
var localItem = item;
//do some operation then set the current item
Application.Current.Dispatcher.Invoke(new Action(() => CurrentItem = localItem ));
}
查看其中的任何一项或所有内容以获取更多信息,或者在Google上搜索“访问修改后的结束”
http://devnet.jetbrains.net/thread/273042