Порядок событий графика - страница 3

 
pavlick_:

Ну началось, асинхронность, постановка в очередь )). Скрипт делает примерно это:

EventChartCustom();  // событие 1

ObjectDelete();    // событие 2

EventChartCustom();  // событие 3

Раз ObjectDelete() это постановка в очередь, т.е. функция не дожидается фактического удаления (возможно), то событие 3 может вполне оказаться раньше события 2 (их приём в OnChartEvent). Может и не так, но с ваших слов как-то так получается.

Нет, с моих слов ничего подобного не получается. Т.к. событие 3 размещается в ту же очередь, что и событие 2, то порядок их обработки совершенно определенный. Вам стоит лучше ознакомиться с понятием "очередь". Ничего сложного нет, даже википедия подойдет.
 
Andrey Khatimlianskii:

pavlick_, можно провести тест: перед удалением объекта захватить его рукой и таскать по графику, тогда он не сможет удалиться (вроде). Тогда станет ясно, когда генерируется событие удаления.

в 5ке удалится
 
Комбинатор:
в 5ке удалится

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Ошибки, баги, вопросы

fxsaber, 2016.10.22 18:40

Очень много времени потратил на локализацию. Советник

class CHARTOBJECT
{
public:
  const string Name;
  const long Chart;

  int GetSubWindow( void ) const
  {
    const ulong StartTime = GetMicrosecondCount();
    
    const int Res = ObjectFind(this.Chart, this.Name);
    
    Print((string)(GetMicrosecondCount() - StartTime) + " mcs.");

    return(Res);
  }

  CHARTOBJECT( const ENUM_OBJECT object_type, const long chart_id = 0  ) :
               Name((string)MathRand()), Chart(chart_id)
  {
    ObjectCreate(this.Chart, this.Name, object_type, 0, 0, 0);
  }

  ~CHARTOBJECT( void )
  {
    if (this.GetSubWindow() != -1)
      ObjectDelete(this.Chart, this.Name);
  }
  
  long GetProperty( const ENUM_OBJECT_PROPERTY_INTEGER Property, const int Modifier = 0 ) const
  {
    return(ObjectGetInteger(this.Chart, this.Name, Property, Modifier));
  }
};

CHARTOBJECT Chart(OBJ_CHART);
CHARTOBJECT* Bitmap;

void OnInit()
{
  Bitmap = new CHARTOBJECT(OBJ_BITMAP_LABEL, Chart.GetProperty(OBJPROP_CHART_ID));
}

void OnDeinit( const int Reason )
{
  Bitmap.GetSubWindow();
  
  delete Bitmap;
}

После того, как его удалите с чарта, будет вывод в лог

2016.10.22 19:35:51.362 Test9 (AUDCAD,M1)       Abnormal termination
2016.10.22 19:35:48.351 Test9 (AUDCAD,M1)       3005619 mcs.

Три секунды он удалялся и вылетел. Воспроизводится только в релиз-варианте. При дебаге все нормально.

Просьба подтвердить у себя. В режиме скрипта воспроизвести не получилось. Только советник.

 
Andrey Khatimlianskii:

pavlick_, можно провести тест: перед удалением объекта захватить его рукой и таскать по графику, тогда он не сможет удалиться (вроде). Тогда станет ясно, когда генерируется событие удаления.

Интересная идея. Проверил, если объект таскать, то попытка удаления закончится неудачей и объект не удалится.

// Скрипт:
void OnStart()
{
   Alert("----------");
   Sleep(2000);
   EventChartCustom(0, 0, 0, 0, "");
   ObjectDelete("ob");
   EventChartCustom(0, 1, 0, 0, "");
}


// Эксперт:
int OnInit()
{
   ChartSetInteger(0, CHART_EVENT_OBJECT_DELETE, true);
   return INIT_SUCCEEDED;
}
void OnChartEvent(const int id,         // идентификатор события
                  const long& lparam,   // параметр события типа long
                  const double& dparam, // параметр события типа double
                  const string& sparam  // параметр события типа string
  )
{
   switch(id)
   {
   case CHARTEVENT_OBJECT_DELETE:
      Alert("CHARTEVENT_OBJECT_DELETE"); return;
   case CHARTEVENT_CUSTOM + 0:
      Alert("CHARTEVENT_CUSTOM + 0"); return;
   case CHARTEVENT_CUSTOM + 1:
      Alert("CHARTEVENT_CUSTOM + 1"); return;
   default:;
   }

Вывод без таскания:

CHARTEVENT_CUSTOM + 1

CHARTEVENT_OBJECT_DELETE

CHARTEVENT_CUSTOM + 0

С тасканием:

CHARTEVENT_CUSTOM + 1

CHARTEVENT_CUSTOM + 0

ЗЫ: у меня МТ4
 
Andrey Khatimlianskii:


Если ObjectDelete() выполняется асинхронно, а событие CHARTEVENT_OBJECT_DELETE создается только по факту удаления, то оно вполне может попасть в эту очередь после "события №3".

Не может. Асинхронность функции в данном случае означает лишь то, что поток программы не будет ждать фактического исполнения команды. Но если вы поставили в очередь чарта команду удаления, а потом команду генерации кастомного события, то не может событие 2 попасть в очередь эксперта после события 3. Событие 3 не будет вычитано из очереди чарта до тех пор, пока не отработается удаление объекта и не сгенерируется событие 2,  т.к. вычиткой очереди чарта, фактическим удалением объекта и генерацией событий чарта занимается один поток.

 
Anton:

Не может. Асинхронность функции в данном случае означает лишь то, что поток программы не будет ждать фактического исполнения команды. Но если вы поставили в очередь чарта команду удаления, а потом команду генерации кастомного события, то не может событие 2 попасть в очередь эксперта после события 3. Событие 3 не будет вычитано из очереди чарта до тех пор, пока не отработается удаление объекта и не сгенерируется событие 2,  т.к. вычиткой очереди чарта, фактическим удалением объекта и генерацией событий чарта занимается один поток.

Вот теперь предельно ясно, спасибо.