如何将此时间关键程序优先于其他线程?

Arn*_*old 3 delphi multithreading

为了编写一个MIDI音序器,我需要一个稳定的脉冲,它调用一个时序例程,该例程具有绝对优先于程序中的任何其他内容,并且优先于计算机中的任何内容.我通过使用TimeSetEvent这样做:

TimeSetEvent (FInterval, 0, TimerUpdate, uInt32 (Self), TIME_PERIODIC);
Run Code Online (Sandbox Code Playgroud)

其中TimerUpdate是一个回调函数,它恢复一个优先级为tpTimeCritical的独立线程,并调用一个例程(FOnTimer)来处理所有MIDI事件.

procedure TThreaded_Timer.Execute;
begin
   if Assigned (FOnTimer) then
   begin
      while not Terminated do
      begin
         FOnTimer (Self);
         if not Terminated then Suspend;
      end; // while
   end; // if
   Terminate;
end; // Execute //
Run Code Online (Sandbox Code Playgroud)

虽然这种结构比我之前尝试的一些东西要好得多,但它仍然对某些事件非常敏感.令我惊讶的是,每次显示提示都会出现断断续续的情况.为什么简单的提示会导致时间关键线程中断?当然我可以把它关掉,但哪些令人讨厌的惊喜还在等着我?

Bri*_*ost 5

使用专为此目的而设计的多媒体计时器.Delphi定时器非常糟糕,只能在空闲时间得到关注.基于线程的计时器仅在该线程受到关注时才有用.MMTimer在内核级别运行,并提供非常重要的回调.我们用它来进行硬件排序自动化控制它是如此的好.

这是我的单位,实现MMTimer作为一个更容易使用的TTimer.使用"重复"使其成为单次或重复.

unit UArtMMTimer;

interface

uses
  Classes,
  SysUtils,
  ExtCtrls,
  MMSystem;

type
  TArtMMTimer = class( TObject )
    constructor Create;
    destructor  Destroy; override;
  PRIVATE
    FHandle              : MMResult;
    FRepeat              : boolean;
    FIntervalMS          : integer;
    FOnTimer             : TNotifyEvent;
    FEnabled             : boolean;
    procedure   RemoveEvent;
    procedure   InstallEvent;
    procedure   DoOnCallback;
    procedure   SetEnabled( AState : boolean );
    procedure   SetIntervalMS( AValue : integer );
  PUBLIC
    property  Enabled : boolean
                read FEnabled
                write SetEnabled;
    property  OnTimer : TNotifyEvent
                read FOnTimer
                write FOnTimer;
    property  IntervalMS : integer
                read FIntervalMS
                write SetIntervalMS;
  end;



implementation

uses
  Windows;


// TArtMMTimer
// --------------------------------------------------------------------


procedure MMTCallBack(uTimerID, uMessage: UINT;
    dwUser, dw1, dw2: DWORD) stdcall;
var
  Timer : TArtMMTimer;
begin
  Timer := TArtMMTimer( dwUser );
  Timer.DoOnCallback;
end;



constructor TArtMMTimer.Create;
begin
  Inherited Create;
  FIntervalMS := 100;
  FRepeat     := True;
end;


destructor  TArtMMTimer.Destroy;
begin
  FOnTimer := nil;
  RemoveEvent;
  Inherited Destroy;
end;


procedure   TArtMMTimer.RemoveEvent;
begin
  If FHandle <> 0 then
    begin
    timeKillEvent( FHandle );
    FHandle := 0;
    end;

end;

procedure   TArtMMTimer.InstallEvent;
var
  iFlags : integer;
begin
  RemoveEvent;

  If FRepeat then
    iFlags := TIME_PERIODIC Or TIME_CALLBACK_FUNCTION
   else
    iFlags := TIME_CALLBACK_FUNCTION;

  FHandle := timeSetEvent(
    FIntervalMS,
    0,
    @MMTCallBack,
    DWord(Self),
    iFlags );
end;

procedure   TArtMMTimer.SetEnabled( AState : boolean );
begin
  If AState <> FEnabled then
    begin
    FEnabled := AState;
    If FEnabled then
      InstallEvent
     else
      RemoveEvent;
    end;
end;



procedure   TArtMMTimer.DoOnCallback;
var
  NowHRCount, WaitHRCount,IntervalHRCount : THRCount;
begin
  If Assigned( FOnTimer ) then
    FOnTimer( Self );
end;


procedure   TArtMMTimer.SetIntervalMS( AValue : integer );
begin
  If AValue <> FIntervalMS then
    begin
    FIntervalMS := AValue;
    If Enabled then
      begin
      Enabled := False;
      Enabled := True;
      end;
    end;
end;

// End TArtMMTimer
// --------------------------------------------------------------------










end.
Run Code Online (Sandbox Code Playgroud)

  • 我不明白,阿诺德已经在使用多媒体计时器了.他的代码正在调用'timeSetEvent',这就是问题所在. (2认同)