基于 QWorker 的多线程编程 – 清理现场

有人雇佣了一些工人干活,但不幸的是,这个人在所有作业完成前,消失在那蓝色星球中的人海找不到了,于是,悲剧的工人在找他要工钱时,发现已经无法找到人了,于是工人暴怒,进行疯狂的破坏,结果就是异常发生了。为了避免工人的暴动,雇主应该在消失之前,清理作业,与工人进行结算,这样才能建设和谐社会嘛。

QWorker 中的作业在提交给 Workers 这个包工头后,作业肯定会访问一些对象、记录或普通的变量,在这些东西失效前,肯定要对相关的作业进行清理,以避免AV错误。在 QWorker 中,提供了 Clear 系列函数来完成此项操作。

    /// <summary>清除所有作业</summary>
    procedure Clear; overload;
    /// <summary>清除一个对象相关的所有作业</summary>
    /// <param name="AObject">要释放的作业处理过程关联对象</param>
    /// <param name="AMaxTimes">最多清除的数量,如果<0,则全清</param>
    /// <returns>返回实际清除的作业数量</returns>
    /// <remarks>一个对象如果计划了作业,则在自己释放前应调用本函数以清除关联的作业,
    /// 否则,未完成的作业可能会触发异常。</remarks>
    function Clear(AObject: Pointer; AMaxTimes: Integer = -1): Integer;
      overload;
    /// <summary>清除所有投寄的指定过程作业</summary>
    /// <param name="AProc">要清除的作业执行过程</param>
    /// <param name="AData">要清除的作业附加数据指针地址,如果值为Pointer(-1),
    /// 则清除所有的相关过程,否则,只清除附加数据地址一致的过程</param>
    /// <param name="AMaxTimes">最多清除的数量,如果<0,则全清</param>
    /// <returns>返回实际清除的作业数量</returns>
    function Clear(AProc: TQJobProc; AData: Pointer; AMaxTimes: Integer = -1)
      : Integer; overload;
    /// <summary>清除指定信号关联的所有作业</summary>
    /// <param name="ASingalName">要清除的信号名称</param>
    /// <returns>返回实际清除的作业数量</returns>
    function Clear(ASignalName: QStringW): Integer; overload;
    /// <summary>清除指定信号关联的所有作业</summary>
    /// <param name="ASingalId">要清除的信号ID</param>
    /// <returns>返回实际清除的作业数量</returns>
    function Clear(ASignalId: Integer): Integer; overload;
    /// <summary>清除指定句柄对应的作业</summary>
    /// <param name="ASingalId">要清除的作业句柄</param>
    /// <returns>返回实际清除的作业数量</returns>
    procedure ClearSingleJob(AHandle: IntPtr); overload;
    /// <summary>清除指定的句柄列表中对应的作业</summary>
    /// <param name="AHandles">由Post/At等投递函数返回的句柄列表</param>
    /// <parma name="ACount">AHandles对应的句柄个数</param>
    /// <returns>返回实际清除的作业数量</returns>
    function ClearJobs(AHandles: PIntPtr; ACount: Integer): Integer; overload;

通过函数的注释,我相信大家已经明白各个清理函数都是干嘛用的了,用的时候,直接调用 Workers.ClearXXX(…) 执行清理过程就好。

如果是分组作业,那么我们该如何怎么办? TQJobGroup 提供了一个 Cancel 函数来完成这项工作。Cancel 函数将取消后续作业的执行,注意其中的 AWaitDone 参数要慎用,如果在分组作业中的作业执行 Cancel 时,必需传递为 False,否则会死等自己结束而不可得。至于其它场合,使用默认值即可。

总之,一个稳定可靠的程序,及时清理不需要的资源是一个良好的工作习惯。

分享到: