gpt4 book ai didi

c# - 使用一个线程多次执行特定任务 C#

转载 作者:行者123 更新时间:2023-11-30 15:28:12 25 4
gpt4 key购买 nike

我有一个与设备一起工作的类,为了避免在使用设备和串行端口时出现 UI 层延迟,我使用了一个线程,但我的设备一次只能完成一项工作。所以,我有一个队列,当用户要求做某事时,任务被添加到队列中,然后我运行一个线程来一个接一个地完成任务。

每次用户请求任务时,我都会检查线程是否正在运行,如果是,我就将新任务添加到队列中,如果不是,我会再次创建线程。这意味着每次队列变空时,我都应该创建一个新线程。现在想请问有什么方法可以复用线程吗?因为我只需要一个线程来完成任务,使用线程池是个好主意吗?由于 suspend 是一种过时的方法,我不知道用户何时会要求另一个任务使用 wait(),我可以暂停线程并以任何其他方式再次运行它吗?或者最好再次创建线程,我做对了吗?

public class Modem
{
Thread thread;
Queue<Task> Tasks = new Queue<Task>();
public Modem()
{
}

public void DoTask(Task s)
{
Tasks.Enqueue(s);
if (thread == null || !thread.IsAlive)
thread = new Thread(HandleTasks);
}

private void HandleTasks()
{
while (Tasks.Count != 0)
SendTaskToModem(Tasks.Dequeue());
}
}

最佳答案

is there any way to reuse the thread? Since I just need one thread to do tasks is it a good idea to use threadpool?

是的,使用 ThreadPool 并依赖框架通常比启动您自己的自定义实现更好。

您可以做的是使用一个后台线程负责处理您的项目,而另一个负责对它们进行排队。这是一个简单的生产者-消费者问题。为此,您可以使用 BlockingCollection:

public class Modem
{
private BlockingCollection<Task> _tasks;
public Modem()
{
_tasks = new BlockingCollection<Task>();
}

public void QueueTask(Task s)
{
_tasks.Add(s);
}

private Task StartHandleTasks()
{
return Task.Run(async () =>
{
while (!_tasks.IsCompleted)
{
if (_tasks.Count == 0)
{
await Task.Delay(100).ConfigureAwait(false);
continue;
}

Task task;
_tasks.TryTake(out task);

if (task != null)
{
// Process item.
}
}
});
}
}

这是使用 BlockingCollection 的一个相当简单的示例。它具有更多内置功能,例如使用 CancellationToken 取消当前正在处理的项目。请注意,您必须添加适当的异常处理、取消等。

使用TPL Dataflow 的@ChrFin 实现为您节省了启动任务处理和在没有任何项目要处理时旋转后台线程的开销。我发布此答案是为了给您提供另一种解决问题的方法。

关于c# - 使用一个线程多次执行特定任务 C#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26083196/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com