Когда энергозависимое ключевое слово должно использоваться в C#?

класс javafx.scene.Node имеет пару методов setUserData (Object) и Object getUserData ()

, которые вы могли бы использовать для добавления вашей информации в узел.

So , вы можете вызвать page.setUserData (info);

И контроллер может проверить, задана ли информация. Кроме того, вы можете использовать ObjectProperty для пересылки данных назад, если это необходимо.

Соблюдайте документацию здесь: http://docs.oracle.com/javafx/2/api/javafx/fxml /doc-files/introduction_to_fxml.html Перед фразой «В первой версии handleButtonAction () помечен с помощью @FXML, чтобы разрешить разметку, определенную в документе контроллера, вызвать ее. Во втором примере поле кнопки аннотируется, чтобы позволить загрузчику устанавливать его значение. Метод initialize () аналогично аннотируется. "

Итак, вам нужно связать контроллер с узлом и установить пользовательские данные для узла.

288
задан Doron Yaacoby 6 December 2008 в 20:04
поделиться

5 ответов

От MSDN: энергозависимый модификатор обычно используется для поля, к которому получают доступ несколько потоков, не используя оператор блокировки для сериализации доступа. Используя энергозависимый модификатор гарантирует, что один поток получает самое актуальное значение, записанное другим потоком.

21
ответ дан Dr. Bob 4 November 2019 в 11:22
поделиться

Если Вы хотите стать немного более техническими о том, что энергозависимое ключевое слово делает, рассматривает следующей программой (я использую DevStudio 2005):

#include <iostream>
void main()
{
  int j = 0;
  for (int i = 0 ; i < 100 ; ++i)
  {
    j += i;
  }
  for (volatile int i = 0 ; i < 100 ; ++i)
  {
    j += i;
  }
  std::cout << j;
}

Используя оптимизированный стандарт (выпускают) параметры компилятора, компилятор создает следующий ассемблер (IA32):

void main()
{
00401000  push        ecx  
  int j = 0;
00401001  xor         ecx,ecx 
  for (int i = 0 ; i < 100 ; ++i)
00401003  xor         eax,eax 
00401005  mov         edx,1 
0040100A  lea         ebx,[ebx] 
  {
    j += i;
00401010  add         ecx,eax 
00401012  add         eax,edx 
00401014  cmp         eax,64h 
00401017  jl          main+10h (401010h) 
  }
  for (volatile int i = 0 ; i < 100 ; ++i)
00401019  mov         dword ptr [esp],0 
00401020  mov         eax,dword ptr [esp] 
00401023  cmp         eax,64h 
00401026  jge         main+3Eh (40103Eh) 
00401028  jmp         main+30h (401030h) 
0040102A  lea         ebx,[ebx] 
  {
    j += i;
00401030  add         ecx,dword ptr [esp] 
00401033  add         dword ptr [esp],edx 
00401036  mov         eax,dword ptr [esp] 
00401039  cmp         eax,64h 
0040103C  jl          main+30h (401030h) 
  }
  std::cout << j;
0040103E  push        ecx  
0040103F  mov         ecx,dword ptr [__imp_std::cout (40203Ch)] 
00401045  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (402038h)] 
}
0040104B  xor         eax,eax 
0040104D  pop         ecx  
0040104E  ret              

Рассмотрение вывода, компилятор решил использовать регистр ecx для хранения значения j переменной. Для энергонезависимого цикла (первое) компилятор присвоил меня регистру eax. Довольно простой. Существует несколько интересных битов, хотя - lea ebx, [ebx] инструкция является эффективно многобайтовой инструкцией по NOP так, чтобы переходы цикла к 16 байтам выровняли адрес памяти. Другой использование edx для постепенного увеличения счетчика цикла вместо того, чтобы использовать inc eax инструкция. Добавление reg, reg инструкция имеет более низкую задержку на нескольких ядрах IA32 по сравнению с inc reg инструкция, но никогда не имеет более высокую задержку.

Теперь для цикла с энергозависимым счетчиком цикла. Счетчик хранится в [ESP], и энергозависимое ключевое слово говорит компилятору, что значение должно всегда читаться из к памяти и никогда не присваиваться регистру. Компилятор даже идет, насколько не сделать загрузку/инкремент/хранилище как три отличных шага (загрузите eax, inc eax, сохраните eax) при обновлении встречного значения вместо этого память непосредственно изменяется в единственной инструкции (добавить мадам, reg). Путем код был создан, гарантирует, что значение счетчика цикла всегда актуально в контексте единственного ядра процессора. Никакая операция на данных не может привести к повреждению или потере данных (следовательно не использующий load/inc/store, так как значение может измениться во время inc, таким образом потерянного на хранилище). Так как прерывания могут только быть обслужены, как только текущая команда завершилась, данные никогда не могут повреждаться, даже с невыровненной памятью.

, Как только Вы представляете второй ЦП системе, энергозависимое ключевое слово не примет меры против данных, обновляемых другим ЦП одновременно. В вышеупомянутом примере Вам были бы нужны данные, которые будут не выровнены для получения потенциального повреждения. Энергозависимое ключевое слово не предотвратит потенциальное повреждение, если данные не могут быть обработаны атомарно, например, если бы счетчик цикла имел тип, долго длинный (64 бита) тогда, то это потребовало бы два 32 битовых операции обновлять значение, посреди которого прерывание может произойти и изменить данные.

Так, энергозависимое ключевое слово только хорошо для выровненных данных, которые меньше чем или равны размеру собственных регистров, таким образом, что операции являются всегда атомарными.

энергозависимое ключевое слово было задумано, чтобы использоваться с операциями IO, где IO будет постоянно изменять, но имел базовый адрес, такой как устройство UART с отображенной памятью, и компилятор не должен продолжать снова использовать первое значение, считанное из адреса.

, Если Вы обрабатываете большие данные или имеете несколько центральных процессоров тогда, Вам будет нужен более высокий уровень (ОС) запирающая система для обработки доступа к данным правильно.

55
ответ дан Tim Cooper 4 November 2019 в 11:22
поделиться

Иногда, компилятор будет оптимизировать поле и использовать регистр для хранения его. Если поток 1 сделает запись к полю, и другой поток получает доступ к нему, так как обновление было сохранено в регистре (и не память), 2-й поток получит устаревшие данные.

можно думать об энергозависимом ключевом слове, что к компилятору "Я хочу, чтобы Вы сохранили это значение в памяти". Это гарантирует, что 2-й поток получает последнее значение.

23
ответ дан Benoit 4 November 2019 в 11:22
поделиться

CLR нравится оптимизировать инструкции, поэтому при доступе к полю в коде, это не могло бы всегда получать доступ к текущему значению поля (это могло бы быть от стека, и т.д.). Отмечание поля как volatile гарантирует, что к текущему значению поля получает доступ инструкция. Это полезно, когда значение может быть изменено (в сценарии без блокировки) параллельным потоком в Вашей программе или некотором другом коде, работающем в операционной системе.

Вы, очевидно, теряете некоторую оптимизацию, но это действительно сохраняет код более простым.

13
ответ дан Joseph Daigle 4 November 2019 в 11:22
поделиться

Я нашел эту статью Joydip Kanjilal очень полезный!

When you mark an object or a variable as volatile, it becomes a candidate for volatile reads and writes. It should be noted that in C# all memory writes are volatile irrespective of whether you are writing data to a volatile or a non-volatile object. However, the ambiguity happens when you are reading data. When you are reading data that is non-volatile, the executing thread may or may not always get the latest value. If the object is volatile, the thread always gets the most up-to-date value

я просто оставлю его здесь для ссылки

1
ответ дан 23 November 2019 в 01:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: