Serg
|
Date: 5/15/2012
Algonavt:
Запущен экспорт стакана ...
Я использую вот такую кострукцию, ктото давно посоветовал спасибо ему за это:
int inUse = Interlocked.CompareExchange(ref _inUse, 1, 0);
if (inUse == 0)
{
try
{
// тут наша обработка
}
catch (Exception onprE)
{
AddLog(StrategyErrorStates.Error, onprE.Message, this);
}
finally
{
Interlocked.Exchange(ref _inUse, 0);
}
}
|
|
|
|
Thanks:
|
|
|
|
|
|
Algonavt
|
Date: 5/15/2012
Ок, спасибо. Хорошая конструкция. Насколько я понимаю из MSDN-овской матчасти о многопоточности, такая конструкция (оформление "чувствительной" части кода в Interlocked) позволяет застраховаться от того, что новый вызов обработчика случится до завершения предыдущего вызова и что часть кода, выполняющая обработку, будет прервана где-то в середине. Верно ли я понимаю, что пока выполняется код в части "// тут наша обработка", все вызовы того же самого обработчика становятся в очередь?
И ещё вопрос. "Замораживается" ли в случае использования такой конструкции содержимое стакана на время выполнения секции " // тут наша обработка"? Я имею в виду, что если в этой секции будет несколько обращений к содержимому стакана (к примеру, получение массива Bid -> выполнение расчетов с массивом Bid -> получение массива Ask -> выполнение расчетов с массивом Ask), есть ли риск того, что между шагами "получение массива Bid" и "получение массива Ask" содержимое стакана изменится?
|
|
|
|
Thanks:
|
|
|
|
|
|
Serg
|
Date: 5/15/2012
|
|
|
|
|
Algonavt:
Верно ли я понимаю, что пока выполняется код в части "// тут наша обработка", все вызовы того же самого обработчика становятся в очередь?
Нет они все проходят мимо так как _inUse у нас теперь равен 1 и (inUse == 0) возвращает false
Algonavt:
И ещё вопрос. "Замораживается" ли в случае использования такой конструкции содержимое стакана на время выполнения секции " // тут наша обработка"? Я имею в виду, что если в этой секции будет несколько обращений к содержимому стакана (к примеру, получение массива Bid -> выполнение расчетов с массивом Bid -> получение массива Ask -> выполнение расчетов с массивом Ask), есть ли риск того, что между шагами "получение массива Bid" и "получение массива Ask" содержимое стакана изменится?
Стакан не замораживается. Насколько я знаю он обновляется в отдельном потоке. И чаще всего вы работаете с его копией делая```csharp
var md = Trader.GetMarketDepth(seccode);
Если дважды вызвать приведенный выше код в "// тут наша обработка" то думаю вероятность есть что первый слепок стакана не будет соответствовать второму.
|
|
|
|
Thanks:
|
|
|
|
|
|
ra81
|
Date: 5/16/2012
Стакан работает не в потоке main вашей программы. Отсюда если ваша программа подвязывается на события обновления стакана то код выполняемый по событию будет тоже в том же потоке что и стакан. Отсюда если вы этот поток задержите, то и приход нового стакана задержится. А код с interlocked по факту задерживает поток стакана. Отсюда сама конструкция не думаю что функциональна вовсе.
Опять же нужно учесть разные устройства коннекторов, но я уверен что каждый новый стакан не приходит в отдельном новом потоке :). Отсюда таки конструкция бесполезна.
|
|
|
|
Thanks:
|
|
|
|
|
|
Serg
|
Date: 5/16/2012
ra81:
Стакан работает не в потоке main вашей программы. Отсюда если ваша программа подвязывается на события обновления стакана то код выполняемый по событию будет тоже в том же потоке что и стакан. Отсюда если вы этот поток задержите, то и приход нового стакана задержится. А код с interlocked по факту задерживает поток стакана. Отсюда сама конструкция не думаю что функциональна вовсе.
Опять же нужно учесть разные устройства коннекторов, но я уверен что каждый новый стакан не приходит в отдельном новом потоке :). Отсюда таки конструкция бесполезна.
Спасибо за ваше мнение заставили меня задуматься)
А как можно всю эту теорию проверить?
|
|
|
|
Thanks:
|
|
|
|
|
|
ra81
|
Date: 5/16/2012
Serg:
ra81:
Стакан работает не в потоке main вашей программы. Отсюда если ваша программа подвязывается на события обновления стакана то код выполняемый по событию будет тоже в том же потоке что и стакан. Отсюда если вы этот поток задержите, то и приход нового стакана задержится. А код с interlocked по факту задерживает поток стакана. Отсюда сама конструкция не думаю что функциональна вовсе.
Опять же нужно учесть разные устройства коннекторов, но я уверен что каждый новый стакан не приходит в отдельном новом потоке :). Отсюда таки конструкция бесполезна.
Спасибо за ваше мнение заставили меня задуматься)
А как можно всю эту теорию проверить?
Проверить легко. В теле обработки стакана поставить Thread.Sleep(100000) и на входе в функцию поставить Debug.WriteLine("Получил стакан.") перед проверкой if (inUse == 0)
Если будете видеть постоянно новые записи значит стакан приходит без задежек. Если будет пауза значит стакан блочится в теле вашей функции.
|
|
|
|
Thanks:
|
|
|
|
|
|
Serg
|
Date: 5/16/2012
Если метод который вы мне предложили верен, то все ок. Блокировки нет. Стакан обновляется в отдельном потоке)
|
|
|
|
Thanks:
|
|
|
|
|
|
ra81
|
Date: 5/16/2012
Serg:
Если метод который вы мне предложили верен, то все ок. Блокировки нет. Стакан обновляется в отдельном потоке)
Ну а реализацию приложите метода с проверкой.... А то странно. Возможно это квиковская особенность.
|
|
|
|
Thanks:
|
|
|
|
|
|
Serg
|
Date: 5/16/2012
|
|
|
|
Thanks:
|
|
|
|
|
|
Maxim
|
Date: 5/16/2012
Serg:
Algonavt:
Запущен экспорт стакана ...
Я использую вот такую кострукцию, ктото давно посоветовал спасибо ему за это:
int inUse = Interlocked.CompareExchange(ref _inUse, 1, 0);
if (inUse == 0)
{
try
{
// тут наша обработка
}
catch (Exception onprE)
{
AddLog(StrategyErrorStates.Error, onprE.Message, this);
}
finally
{
Interlocked.Exchange(ref _inUse, 0);
}
}
Я обычно такой конструкцией пользуюсь.
```csharp
if (Monitor.TryEnter(lockObject) == true)
{
try
{
// Код, который необходимо выполнить только в одном потоке одновременно
}
finally
{
Monitor.Exit(lockObject);
}
}
else
{
// Если у нас не получилось блокировать
}
|
|
|
|
Thanks:
|
|
|
|
|