Резьбовая проблема приложения

У меня возникла проблема, когда первый элемент в коллекции отвечает на обновление, но нет других (из 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);
            }

Код для обновления предметов. Вид привязан к свойствам здесь (особенно CurrentItem). Предметы - это 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));
}

Пока я прохожу (с помощью отладочного конвертера), я замечаю, что элемент обновляется только в первый раз. Остальное просто проходит. У меня есть свойство CurrentItem с DependencyProperty.

Я пытался использовать CheckAccess, чтобы использовать свойство Delegate и udpate, и это тоже не помогло.

Любая помощь приветствуется и спасибо!

1 ответ

Ваша проблема не имеет ничего общего с многопоточностью, она связана с тем, как замыкания захватывают переменные в вашем последнем фрагменте кода. Вы все лямбы разделяете одну переменную, то есть item переменная. Так как ваша лямда бежит после окончания цикла item всегда будет установлен последний элемент в коллекции элементов. (Хотя они могут запускаться с любым предметом, в зависимости от того, когда именно он будет запущен)

Компилятор преобразует:

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

Доступ к измененному закрытию

Доступ к измененному закрытию (2)

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

Другие вопросы по тегам