c# - 如何在 C# 中运行可变数量的并发参数化无限循环类型的线程?
问题描述
我正在创建我的第一个基于多线程 C#/.NET 的应用程序,它将在 Azure Service Fabric 集群上运行。正如标题所说,我希望运行可变数量的并发参数化无限循环类型的线程,这将利用 RunAsync 方法。
每个子线程看起来像这样:
public async Task childThreadCall(...argument list...)
{
while (true)
{
try
{
//long running code
//do something useful here
//sleep for an independently parameterizable period, then wake up and repeat
}
catch (Exception e)
{
//Exception Handling
}
}
}
在 RunAsync 方法中调用的此类子线程数量不定。我想做这样的事情:
protected override async Task RunAsync(CancellationToken cancellationToken)
{
try
{
for (int i = 0; i < input.length; i++)
{
ThreadStart ts[i] = new ThreadStart(childThreadCall(...argument list...));
Thread tc[i] = new Thread(ts);
tc[i].Start();
}
}
catch (Exception e)
{
//Exception Handling
}
}
所以基本上每个子线程都独立于其他线程运行,并且永远这样做。有可能做这样的事情吗?有人能指出我正确的方向吗?有什么陷阱需要注意吗?
解决方案
该RunAsync
方法在服务启动时被调用。所以是的,它可以用来做你想做的事。我建议使用任务,因为它们可以很好地与取消令牌配合使用。这是一个粗略的草稿:
protected override async Task RunAsync(CancellationToken cancellationToken)
{
var tasks = new List<Task>();
try
{
for (int i = 0; i < input.length; i++)
{
tasks.Add(MyTask(cancellationToken, i);
}
await Task.WhenAll(tasks);
}
catch (Exception e)
{
//Exception Handling
}
}
public async Task MyTask(CancellationToken cancellationToken, int a)
{
while (true)
{
cancellationToken.ThrowIfCancellationRequested();
try
{
//long running code, if possible check for cancellation using the token
//do something useful here
await SomeUseFullTask(cancellationToken);
//sleep for an independently parameterizable period, then wake up and repeat
await Task.Delay(TimeSpan.FromHours(1), cancellationToken);
}
catch (Exception e)
{
//Exception Handling
}
}
}
关于陷阱,有一个很好的列表,列出了在使用任务时一般要考虑的事情。
请注意,任务最适合 I/O 绑定工作。如果您可以发布在长期运行过程中究竟做了什么,那么我可以改进答案以最适合您的用例。
一件重要的事情是尊重传递给 RunAsync 方法的取消令牌,因为它表明服务即将停止。它让您有机会优雅地停止工作。从文档:
确保传递给 RunAsync(CancellationToken) 的 cancelToken 得到兑现,一旦发出信号, RunAsync(CancellationToken) 就会尽快正常退出。请注意,如果 RunAsync(CancellationToken) 已经完成了它的预期工作,它不需要等待 cancelToken 发出信号并且可以优雅地返回。
正如您在我的代码中看到的那样,我将传递CancellationToken
给子方法,以便他们可以对可能的取消做出反应。在您的情况下,由于无限循环,将会取消。
推荐阅读
- c# - 当我尝试“将项目与 gradle 文件同步”时,会弹出一个警告
- python - 如何在 mac 上安装 jupyter notebook?
- javascript - 当我尝试在单击时添加图像时,Javascript appendChild() 不起作用
- c++ - 对链表的值进行排序并打印它们
- java - Android Studio 4.1.2 无法从 github 同步 onedrive-picker-android-master 项目
- swift - 有没有办法在 Swift 包中包含标题
- node.js - 查找关系是否存在并将其映射到 typeorm 中的布尔值
- reactjs - 使用带有 Material-UI 输入的 rc-time-picker
- java - 彻底关闭 Spring WebSockets STOMP 客户端
- python - Python Pandas 将列字符串值拆分为单独的列