Work Control - ZjzMisaka/PowerThreadPool.zh-CN.Wiki GitHub Wiki
Pause(...)
暂停线程池或任务, 可以使用 work id(s)
作为参数.
Resume(...)
恢复线程池或任务, 可以使用 work id(s)
作为参数.
Stop(...)
停止线程池或任务, 可以使用 work id(s)
和 强制停止标志
作为参数.
Wait[Async](...)
阻塞并等待线程池或任务完成, 可以使用 work id(s)
作为参数.
Fetch[Async](...)
阻塞并获取任务结果, 可以使用 work id(s)
或 谓词函数
以及 获取后从存储中移除结果标志
作为参数.
Cancel(...)
取消尚未开始的任务, 可以使用 work id(s)
作为参数.
PauseIfRequested()
在任务逻辑中插入一个暂停点.
StopIfRequested(...)
在任务逻辑中插入一个停止点, 可以使用 在停止过程前执行的函数
作为参数.
CheckIfRequestedStop()
在任务逻辑中插入一个检查点, 查看是否通过调用 Stop(...) 请求了停止.
PowerPool powerPool = new PowerPool();
string id0 = powerPool.QueueWorkItem(() =>
{
while (true)
{
powerPool.PauseIfRequested();
if (powerPool.CheckIfRequestedStop())
{
return true;
}
// Do something
}
});
Task<ExecuteResult<bool>> resultTask = powerPool.FetchAsync<bool>(id0);
powerPool.Pause();
powerPool.Resume();
powerPool.Stop();
powerPool.Wait();
ExecuteResult<bool> result = await resultTask;
string id1 = powerPool.QueueWorkItem(() =>
{
while (true)
{
powerPool.PauseIfRequested();
powerPool.StopIfRequested();
// Do something
}
});
powerPool.Pause(id1);
powerPool.Resume(id1);
powerPool.Stop(id1);
powerPool.Wait(id1);
由于 Thread.Abort
, Thread.Suspend
和 Thread.Resume
可能导致不可预测的行为, 它们在较新的 .NET 版本中已被弃用, 因此 PowerThreadPool 库也不使用这些 API 来控制线程.
PowerThreadPool 封装了 CancellationTokenSource
和 ManualResetEvent
的操作, 提供了协作式的线程池和任务控制.
可以在任务逻辑中插入 PauseIfRequested()
, StopIfRequested(...)
或 CheckIfRequestedStop()
(例如在循环或耗时逻辑的节点中), 以管理执行流程. 当调用 Pause, Resume 或 Stop 函数时, 逻辑将在预期位置暂停, 恢复或停止. 使用任务 ID 作为这些函数的参数可以确保其他任务不受影响.
- PauseIfRequested():在任务逻辑中调用此函数, 当用户调用 Pause(...) 时, 任务将在此处暂停.
-
StopIfRequested(Func<bool> beforeStop = null):在任务逻辑中调用此函数, 当用户调用 Stop(...) 时, 任务将在此处停止.
为了退出逻辑, 该函数将抛出PowerThreadPool.Exceptions.WorkStopException
.WorkStopException
仅用于停止任务, 不要捕获它, 因为 PowerThreadPool 会处理它.
如果你希望在停止之前执行某些操作 (例如释放一些非托管资源)或在某些情况下阻止停止, 建议使用参数beforeStop
.
如果不希望以这种方式退出逻辑, 也可以使用CheckIfRequestedStop
. -
CheckIfRequestedStop():在任务逻辑中调用此函数, 以检查是否已请求停止 (如果用户调用了 Stop(...)).
当返回 true 时, 你可以执行一些预处理操作 (如释放非托管资源), 然后安全地退出逻辑. 根据情况, 你甚至可以选择忽略停止请求.
以这种方式停止任务不会触发WorkStopped
事件, 而是被视为任务已正常完成.
string workID = powerPool.QueueWorkItem(() =>
{
while (true)
{
powerPool.PauseIfRequested();
powerPool.StopIfRequested();
// Do something
}
});
string workID = powerPool.QueueWorkItem(() =>
{
while (true)
{
powerPool.PauseIfRequested();
powerPool.StopIfRequested(() =>
{
// Do something before return
if (/* 你希望继续停止 */)
{
return true;
}
else
{
return false;
}
});
// Do something
}
});
string workID = powerPool.QueueWorkItem(() =>
{
while (true)
{
if (powerPool.CheckIfRequestedStop())
{
// Do something before return
return;
}
// Do something
}
});
powerPool.Pause();
powerPool.Pause(workID);
powerPool.Pause(workIDList);
powerPool.Resume();
powerPool.Resume(workID);
powerPool.Resume(workIDList);
powerPool.Stop();
powerPool.Stop(workID);
powerPool.Stop(workIDList);
当 Stop
函数接受布尔参数 (即 forceStop
)为 true 时, 即使任务逻辑中未插入 StopIfRequested(...)
, 它也可以停止线程, 因为将调用 Thread.Interrupt()
. 线程池将在捕获 ThreadInterruptedException 后立即终止线程.
虽然这种方式比 Thread.Abort
更安全, 但从业务逻辑的角度来看, 它仍可能导致不可预知的结果, 且无法保证退出线程所需的时间, 因此应尽量避免使用强制停止.
以这种方式停止的线程将被销毁, 不会被保留.
string workID = powerPool.QueueWorkItem(() =>
{
while (true)
{
// Do something
}
});
powerPool.Stop(true);
powerPool.Stop(workID, true);
powerPool.Stop(workIDList, true);
调用线程可以被阻塞, 直到所有任务终止.
可以使用任务 ID 作为 Wait 的参数, 确保其他任务不受影响.
Wait
的异步版本是 WaitAsync
.
powerPool.Wait();
powerPool.Wait(workID);
powerPool.Wait(workIDList);
Fetch
函数用于获取任务的结果. 调用后, 将在任务完成时返回 ExecuteResult.
需要 workID
或 workIDList
作为参数.
通常, Fetch
函数用于获取尚未开始或正在进行中的任务的结果.
此函数是阻塞的, 意味着它将暂停调用线程的执行, 直到指定的任务完成并返回结果.
对于非阻塞行为, 可以使用 FetchAsync
函数. 此函数允许异步获取任务的结果, 而不会中断调用线程的执行.
需要 谓词函数
作为参数.
它将根据谓词函数从现有结果中搜索匹配的结果集合. 谓词函数是一个接受 ExecuteResult<TResult>
作为参数并返回 bool
值的函数, 类似于 LINQ 中的 Where
.
由于它从已有结果中筛选, 不会导致阻塞, 因此没有异步版本.
Fetch
的异步版本是 FetchAsync
.
powerPool.Fetch(workID);
powerPool.Fetch(workIDList);
powerPool.Fetch<int>(x => x.Result >= 3);
默认情况下, 为了防止内存泄漏, 线程池不存储任务执行结果. 如果你希望保留已完成任务的结果, 应将 WorkOption.ShouldStoreResult
设置为 true, 这会指示线程池在任务完成后保存结果.
有三种方式可以清除已保存的执行结果:
- 将
PowerPoolOption.ClearResultStorageWhenPoolStart
设置为 true. 这将在线程池重新进入运行状态时清除已保存的执行结果.
PowerPool powerPool = new PowerPool(new PowerPoolOption() { ClearResultStorageWhenPoolStart = true });
- 将
Fetch
函数的可选参数设置为 true (Fetch(workID, true)
), 这样在调用Fetch
时, 任务 ID 对应的执行结果将被清除.
powerPool.Fetch(workID, true);
powerPool.Fetch(workIDList, true);
- 直接调用
PowerPool.ClearResultStorage(...)
.
powerPool.ClearResultStorage();
powerPool.ClearResultStorage(workID);
powerPool.ClearResultStorage(workIDList);
Cancel
函数用于取消尚未开始的任务.
可以使用任务 ID 作为 Cancel 的参数, 确保其他任务不受影响.
powerPool.Cancel();
powerPool.Cancel(workID);
powerPool.Cancel(workIDList);