2015-02-20 2 views
-1

Я вызываю форму «Найти» из FrmDelivery. Форма «Поиск» сбой при попытке сканирования штрих-кода в поле редактирования (тот же код отлично работает в другом месте приложения, например, в FrmDelivery).Возможно ли, чтобы события закрытой формы загорелись?

Файл журнала показывает, что FrmDelivery это форма переживания исключение:

Message: Reached frmDelivery.StartRead 

Date: 2/19/2015 7:39:39 PM 
Message: From FrmDelivery.StartRead(): The scanner not enabled, Call Enable() first.; Inner Ex: ; Stack Trace: at 
Symbol.Barcode.Actions.Read(ReaderData rd) 

Тем не менее, до открытия формы Find, я закрываю FrmDelivery ("это" ниже):

private void buttonFind_Click(object sender, EventArgs e) 
{ 
    ExceptionLoggingService.Instance.WriteLog("Reached frmDelivery.buttonFind_Click"); 
    this.Close(); // Close the Delivery form; this still leaves frmMain up 
    const HHSConsts.RecordTypes rt = HHSConsts.RecordTypes.Delivery; 
    frmFind ff = new frmFind(rt, dsdName); 
    ff.ShowDialog(); 
} 

StartRead() - метод, исключающий исключение:

private void StartRead() 
{ 
    ExceptionLoggingService.Instance.WriteLog("Reached 
frmDelivery.StartRead"); 
    try 
    { 
     // If we have both a reader and a reader data 
     if ((this.barcodeReader != null) && (this.barcodeReaderData != 
null)) 
     { 
      if (this.barcodeReaderData.IsPending) return; 
      // Submit a read 
      this.barcodeReader.ReadNotify += this.barcodeEventHandler; 
      this.barcodeReader.Actions.Read(this.barcodeReaderData); 
     } 
    } 
    catch (Exception ex) 
    { 
     String msgInnerExAndStackTrace = String.Format(
       "{0}; Inner Ex: {1}; Stack Trace: {2}", ex.Message, 
ex.InnerException, ex.StackTrace); 
     ExceptionLoggingService.Instance.WriteLog(String.Format("From 
FrmDelivery.StartRead(): {0}", msgInnerExAndStackTrace)); 
    } 
} 

// StartRead() называется четырехместным s в FrmDelivery:

private void textBoxUPC_PLU_GotFocus(object sender, EventArgs e) 
{ 
    textBoxUPC_PLU.BackColor = HHSConsts.BARSCAN_COLOR; // Why is this 
not sticking? 
    ExceptionLoggingService.Instance.WriteLog("Reached 
frmDelivery.textBoxUPC_PLU_GotFocus"); 
    if (this.InitReader()) 
    { 
     this.StartRead(); 
    } 
} 

private void BarcodeReader_ReadNotify(object sender, EventArgs e) 
{ 
    ExceptionLoggingService.Instance.WriteLog("Reached 
frmDelivery.BarcodeReader_ReadNotify"); 
    try 
    { 
     Symbol.Barcode.ReaderData TheReaderData = 
this.barcodeReader.GetNextReaderData(); 

     if (TheReaderData.Result == Symbol.Results.SUCCESS) 
     { 
      // Handle the data from this read 
      this.HandleData(TheReaderData); 
      // Start the next read 
      this.StartRead(); 
     } 
    } 
    catch (Exception ex) 
    { 
     String msgInnerExAndStackTrace = String.Format(
       "{0}; Inner Ex: {1}; Stack Trace: {2}", ex.Message, 
ex.InnerException, ex.StackTrace); 
     ExceptionLoggingService.Instance.WriteLog(String.Format("From 
FrmDelivery.BarcodeReader_ReadNotify(): {0}", 
msgInnerExAndStackTrace)); 
    } 
} 

private void ReaderForm_Activated(object sender, EventArgs e) 
{ 
    ExceptionLoggingService.Instance.WriteLog("Reached 
frmDelivery.ReaderForm_Activated"); 
    // If there are no reads pending on barcodeReader, start a new read 
    if (!this.barcodeReaderData.IsPending) 
    { 
     this.StartRead(); 
    } 
} 

private void textBoxId_GotFocus(object sender, EventArgs e) 
{ 
    ExceptionLoggingService.Instance.WriteLog("Reached 
frmDelivery.textBoxId_GotFocus"); 
    if (this.InitReader()) 
    { 
     this.StartRead(); 
    } 
} 

Но как любой этих методов называют StartRead() после того, как форма была закрыта?

+1

Я смущен: вы говорите, что форма поиска сбой, но выдержка из журнала, кажется, говорит, что frmDelivery является источником, который также называется формой, закрытой в первом блоке кода. Во всяком случае, frmДоставка диалога тоже? – Plutonix

+0

Да, это мой вопрос - почему зажигаются события закрытой формы? FrmDelivery вызывается из frmMain через ShowDialog(); frmFind вызывается из FrmDelivery с помощью ShowDialog(). –

+2

Боковое примечание: 'this.barcodeReader.ReadNotify + = this.barcodeEventHandler;' выглядит как проблема, потому что кажется, что он многократно добавляет этот обработчик событий. Это может сделать метод несколько раз. – LarsTech

ответ

1

& hellip; как мог любой из этих методов вызвать StartRead() после того, как форма была закрыта?

Это зависит. Является ли объект считывателя штрих-кода еще вокруг? То есть на что он ссылается?

Закрытие формы делает одну из двух вещей, в зависимости от того, является ли она модальной или нет: скрывает окно (для модальных окон) или закрывает и открывает окно (для немодальных окон). Это почти все, что вам гарантировано (не считая другой логики, которую вы добавляете, например, обработчик события FormClosed).

В частности, закрытие формы делает не каким-либо образом само по себе заставляет этот объект быть собранным или иным образом отключенным от мусора. Многие формы ссылаются только на структуру Winforms и при закрытии эти ссылки отбрасываются. Но если вы сделаете что-нибудь, чтобы заставить вашу форму ссылаться в другом месте, она будет жить.

Форма FrmDelivery, похоже, подписана на событие ReadNotify объекта считывателя штрих-кода. Это включает добавление экземпляра делегата в список вызовов для события, а так как метод обработчика событий является методом экземпляра, этот экземпляр делегирования включает ссылку на объект FrmDelivery.

Пока объект считывания штрих-кода по-прежнему доступен (или если это класс static, и, следовательно, все его элементы всегда достижимы), это означает, что ваш объект FrmDelivery также доступен. То есть, объект считывателя штрих-кода сохраняет объект-делегат, который, в свою очередь, ссылается на объект FrmDelivery.

Поскольку метод обработчика событий на самом деле является одним из способов вызова метода StartRead(), кажется очень вероятным, что это на самом деле то, что происходит. Недостаточно контекста в вашем примере кода для тех, кто его читает, абсолютно уверен, но вероятность очень высока. Было бы неплохо.:)


Кстати, помимо подписки обработчика событий (который из описания проблемы выглядит, как он будет держать FrmDelivery объект живым в любом случае), вы, кажется, гнездящихся ваши ShowDialog() звонки таким образом, что также предотвратит сбор объекта FrmDelivery.

В частности: вы вызываете Close() на объект FrmDelivery в обработчике события для кнопки на форме. Этот обработчик не возвращается до тех пор, пока метод ShowDialog() не вызовет вызов этого обработчика, и пока обработчик не вернется, ваш исходный вызов ShowDialog() для окна FrmDelivery не сможет вернуться, и до тех пор, пока не будет вызван вызов ShowDialog(), вызывающий объект этого метода не может распоряжаться или иным образом отменить экземпляр формы.

Это не имеет никакого отношения к тому, вызван ли сам обработчик событий, но он влияет на время жизни объекта.