TThread работает по-другому в консольном приложении Delphi 2006 года?

Почему привязка TextBox не работает правильно в первом примере?

Это потому, что TypeDescriptor из DataRow не имеет свойства Id. Рассмотрим следующие правила:

  • Когда привязка данных к свойству элемента, дескриптор типа элемента должен содержать свойство с таким именем.

  • При привязке данных к списку дескриптор типа элемента списка должен содержать свойство с таким именем.

Верно ли говорить, что автоматическое (без какого-либо дополнительного вызова для связывания do) распространение из источника в управление происходит только с DataRow?

Нет. Это не из-за типа DataRow. Это из-за INotifyPropertyChanged и IBindingList. Рассмотрим следующие правила:

  • Когда данные связывают элемент управления с элементом, если элемент реализует INotifyPropertyChanged, пользовательский интерфейс будет обновляться сразу после обновления элемента.

  • При привязке данных к элементу управления списком, если элемент реализует INotifyPropertyChanged и список реализует IBindingList, пользовательский интерфейс будет обновляться сразу после обновления элемента или списка.

Дополнительная информация

Коротко о том, что я описал выше, вы можете найти в Привязка данных Windows Forms . Я рекомендую прочитать следующие полезные документы:

6
задан Steve 7 November 2008 в 18:32
поделиться

2 ответа

Необходимо обеспечить больше данных.

Обратите внимание, что через OnTerminate называют, Синхронизируются, который требует вызова к CheckSynchronize в какой-то момент где-нибудь. Приложение. ProcessMessages обычно делает это, но в зависимости от того, как VCL был инициализирован, возможно, что Синхронизировать механизм не был полностью сцеплен вместе в консольном приложении.

В любом случае эта программа работает как ожидалось над моей машиной:

uses Windows, SysUtils, Classes, Forms;

var
  threadCount: Integer;

type
  TMyThread = class(TThread)
  public
    procedure Execute; override;
    class procedure Go;
    class procedure HandleOnTerminate(Sender: TObject);
  end;

procedure TMyThread.Execute;
begin
end;

class procedure TMyThread.Go;
  function MakeThread: TThread;
  begin
    Result := TMyThread.Create(True);
    Inc(threadCount);
    Result.OnTerminate := HandleOnTerminate;
  end;
var
  t1, t2, t3: TThread;
begin
  t1 := MakeThread;
  t2 := MakeThread;
  t3 := MakeThread;
  t1.Resume;
  t2.Resume;
  t3.Resume;
  while threadCount > 0 do
    Application.ProcessMessages;
end;

class procedure TMyThread.HandleOnTerminate(Sender: TObject);
begin
  InterlockedDecrement(threadCount);
end;

begin
  try
    TMyThread.Go;
  except
    on e: Exception do
      Writeln(e.Message);
  end;
end.
8
ответ дан 8 December 2019 в 18:43
поделиться

Как Barry справедливо указал, если CheckSyncronize не называют, Синхронизируйтесь, не назван, и если синхронизируются, не назван, то событие OnTerminate не запущено. То, что, кажется, происходит, - то, что, когда я выполняю свои Модульные тесты как консольное приложение, нет никаких сообщений на очереди сообщений и таким образом Приложения. ProcessMessage, который называют от Processmessages, никогда не добирается для вызова checkSynchronize. Я теперь решил проблему путем изменения цикла на

While fThreadRefCount > 0 do
begin
   Application.ProcessMessages;
   CheckSynchronize;
end;

Это теперь работает и в консоли и в gui режимах.

Целый рычаг wakeupmainthread, кажется, установка правильно. Именно этот рычаг добавляет сообщение WM_NULL, которое инициировало checksynchronize. Это просто не получает это далеко в консольном приложении.

Больше расследования

Поэтому Синхронизируйтесь, действительно становится названным. Вызовы DoTerminate Синхронизируются (CallOnTerminate), но там существует строка:

WaitForSingleObject(SyncProcPtr.Signal, Infinite); 

который просто ожидает навсегда.

Таким образом, в то время как моя фиксация выше работ, существует что-то глубже к этому!

5
ответ дан 8 December 2019 в 18:43
поделиться
Другие вопросы по тегам:

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