gpt4 book ai didi

c# - 线程应用问题

转载 作者:行者123 更新时间:2023-12-03 13:21:53 25 4
gpt4 key购买 nike

我遇到了一个问题,即集合中的第一个项目正在响应更新,但没有其他项目(共 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 绑定(bind)到这里的属性(尤其是 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 属性,但这也没有帮助。

欢迎任何帮助,谢谢!

最佳答案

您的问题与多线程无关,它与闭包如何在最后一个代码片段中捕获变量有关。你的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

Access to Modified Closure

Access to Modified Closure (2)

http://weblogs.asp.net/fbouma/archive/2009/06/25/linq-beware-of-the-access-to-modified-closure-demon.aspx

关于c# - 线程应用问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6605374/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com