Delphi 2009 ждет обход цепочки, доступный в установках Windows 7?

Согласно «Что нового в Delphi 2009», есть новые функции отладчика, называемые «обход цепочки ожидания». В нем конкретно говорится: «Функция обхода цепочки ожидания была добавлена, чтобы помочь вам разрешить конфликты потоков или проблемы с взаимоблокировкой». Эта функция использует средство, добавленное в операционную систему Windows Vista, которое предоставляет информацию отладчику о состоянии ожидания потоков вашего приложения в форма цепочки ожидания ».

Delphi 2009 был выпущен, когда Windows Vista была текущей операционной системой. По моему опыту, большинство функций, представленных в Vista, также доступны в Windows 7. Однако я не вижу эту функцию в своих установках Delphi 2009 через Delphi XE (все в Windows 7).

Я ищу эту функцию на панели потоков отладчика.

  1. Ищу ли я обход цепочки ожидания в правильном месте?

  2. Действительно ли эта функция доступна только в Windows Vista, а не в Windows 7?

Дэвид М. дал хороший и ясный ответ, но я до сих пор не вижу столбца «Цепочка ожидания» на панели потоков. Вот код.

Основная форма:

unit Main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, SyncObjs, RanThread;

type
  TForm1 = class(TForm)
    ListBox1: TListBox;
    Button1: TButton;
    Button2: TButton;
    Label1: TLabel;
    procedure Button2Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    procedure ThreadDone(Sender: TObject);
  end;

var
  Form1: TForm1;
  RanGenThread: TRandomizer;

implementation

uses LoadThread;

{$R *.dfm}

{ TForm1 }

procedure TForm1.ThreadDone(Sender: TObject);
begin
  RanGenThread.Free;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
ListBox1.Sorted := True;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Thread: TLoader;
begin
ListBox1.Items.Clear;
ListBox1.Sorted := False;
RanGenThread := TRandomizer.Create(True);
RanGenThread.ArraySize := 1000;
Thread := TLoader.Create(True);
with Thread do
begin
  RanGenThread.WaitThread := Thread;
  FreeOnTerminate := True;
  OnTerminate := ThreadDone;
  WaitForThread := RanGenThread;
  //Use Start in Delphi 2010 or later, where Resume is deprecated
  Resume;
end;
RanGenThread.Resume;
end;

initialization
  Randomize;

end.

TRandomizer:

unit RanThread;

interface

uses
  Classes, Math, SyncObjs;

type
  TRandomizer = class(TThread)
  private
    { Private declarations }
    FArraySize: Integer;
  protected
    procedure Execute; override;
  public
    WaitThread: TThread;
    RandNumbers: array of Integer;
    property ArraySize: Integer read FArraySize write FArraySize;

  end;

implementation

uses Main;

procedure TRandomizer.Execute;
var
  i: Integer;
  LowNum, HighNum: Integer;
  RandNum: Integer;
begin
if FArraySize = 0 then
  begin
    Exit;
  end;
SetLength(RandNumbers, FArraySize);
LowNum := Low(RandNumbers);
HighNum := High(RandNumbers);
//initialize the array
for i := LowNum to HighNum do
  RandNumbers[i] := -1;
// generate the random order
for i := LowNum to HighNum do
  while True do
    begin
      RandNum := RandomRange(LowNum, HighNum + 1);
      if RandNumbers[RandNum] = -1 then
      begin
        RandNumbers[RandNum] := i + 1;
        break;
      end; // if
    end; // while
    WaitThread.WaitFor;
end;

end.

TLoader:

unit LoadThread;

interface

uses
  Classes, SyncObjs, Dialogs, SysUtils, RanThread;

type
  TLoader = class(TThread)
  private
    FWaitForThread: TRandomizer;
    procedure UpdateList;
    { Private declarations }
  protected
    procedure Execute; override;
  public
    property WaitForThread: TRandomizer
      read FWaitForThread write FWaitForThread;
  end;

implementation

uses Main;

procedure TLoader.UpdateList;
var
 i: Integer;
begin
for i := Low(FWaitForThread.RandNumbers) to
  High(FWaitForThread.RandNumbers) do
  Form1.ListBox1.Items.Add(IntToStr(FWaitForThread.RandNumbers[i]));
end;

procedure TLoader.Execute;
begin
if WaitForThread <> nil then
begin
  FWaitForThread.WaitFor;
  Synchronize(UpDateList)
end;
end;

end.

Согласно документу обхода цепочки ожидания, с которым связан Дэвид М., WTC доступен для следующих объектов синхронизации:

  • ALPC
  • COM
  • Критические разделы
  • Мьютексы
  • SendMessage
  • Операции ожидания в процессах и потоках

Мой код ожидает в потоке, но это TThread, а не непосредственно собственный поток. Этим вечером я изменю свой пример кода так, чтобы он блокировался при ожидании Mutex, и посмотрите, приведет ли это к появлению столбца «Цепочка ожидания» на панели потоков.

OK. Наконец-то нашлось время для следующего теста. Создал приложение, которое стало владельцем Mutex при запуске. Создал рабочий поток, который использовал OpenMutex для получения дескриптора этого Mutex, а затем вызвал WaitForsingleObject (handle, INFINITE). По-прежнему нет столбца цепочки ожидания на панели потоков.

9
задан Cary Jensen 10 November 2010 в 00:43
поделиться