c#等待线程的多线程问题
在浏览了这个论坛上的许多帖子以及其他关于c#多线程的帖子之后,我仍然感到困惑,并且在处理这个问题时遇到了问题 我想创建c#等待线程的多线程问题,c#,multithreading,C#,Multithreading,在浏览了这个论坛上的许多帖子以及其他关于c#多线程的帖子之后,我仍然感到困惑,并且在处理这个问题时遇到了问题 我想创建numThreads线程数,以便为documentIds中的每个整数执行一个函数documentIds是一个计数为100的列表,我想在documentIds中的每个元素上调用resitchworker.resitch 我目前拥有的是以下内容,但我对如何保持5个线程在100个DocumentID列表中循环感到困惑。。。感谢所有的帮助 for (int i = 0; i < d
numThreads
线程数,以便为documentIds
中的每个整数执行一个函数documentIds
是一个计数为100的列表,我想在documentIds
中的每个元素上调用resitchworker.resitch
我目前拥有的是以下内容,但我对如何保持5个线程在100个DocumentID列表中循环感到困惑。。。感谢所有的帮助
for (int i = 0; i < documentIds.Count; i++)
{
if (threadCount < numThreads)
{
var Worker = new RestitchWorker(documentIds.ElementAt(i));
Thread t_restitchWorker = new Thread(() => Worker.Restitch());
threadCount++;
t_restitchWorker.Start();
t_restitchWorker.Join();
}
}
for(int i=0;iWorker.resitch());
threadCount++;
t_resitchworker.Start();
t_resitchworker.Join();
}
}
这个问题更适合于任务而不是线程。如果对于您的问题,没有必要显式创建线程;然后,由于线程管理可能会很昂贵,因此线程池可以更有效
任务适合于需要松散地并行完成100个长作业的问题,因为它们将汇集线程而不是创建100个显式线程,并且具有支持等待多个任务的易于使用的API
任务列表
您可以通过创建任务列表并调用System.Threading.tasks.Task.WaitAll
:
var tasks = new List<Task>();
for (int i = 0; i < n; ++i)
{
tasks.Add(Task.Run(action: SomeLongTask));
}
Task.WaitAll(tasks);
应用程序中有许多多线程机制。您可以使用异步任务、任务并行库(TPL)、线程池、信号量等。当我需要对一次生成的线程数量进行高度控制时,我使用的机制是使用信号量LIM,设置最大线程数,然后使用Wait
等待新线程可用。我将把我的数据(例如文档ID列表)放入ConcurrentQueue
中,这样我就可以安全地排队和出列线程执行工作所需的信息,而不必担心(太多)线程安全。异步任务可用于实际开始执行工作
static class Program
{
private const int _maxWorkers = 10;
private static readonly SemaphoreSlim _threadManager = new SemaphoreSlim(_maxWorkers);
private void DoStuff()
{
var queue = new ConcurrentQueue<int>(SomeClass.GetDocumentIds());
var operations = new List<Task>();
while (!queue.IsEmpty)
{
int documentId;
if (queue.TryDequeue(out documentId))
{
_threadManager.Wait(); // this will block after max number of threads is met
try
{
operations.Add(GetDocument(documentId);
}
catch (Exception)
{
// ignored
}
}
}
Task.WaitAll(operations.ToArray()); // finally, this waits till the last remaining tasks are complete
}
private static async Task GetDocument(int documentId)
{
await Task.Yield();
try
{
GoGetDocument(documentId);
}
catch (Exception)
{
// ignored
}
finally
{
_threadManager.Release(); // release the semaphore when the task completes
}
}
静态类程序
{
私有const int_maxWorkers=10;
私有静态只读信号量lim _threadManager=新信号量lim(_maxWorkers);
私人无效文件()
{
var queue=新的ConcurrentQueue(SomeClass.getDocumentId());
var operations=新列表();
而(!queue.IsEmpty)
{
int documentId;
if(queue.TryDequeue(out documentId))
{
_threadManager.Wait();//这将在满足最大线程数后阻塞
尝试
{
添加(GetDocument(documentId);
}
捕获(例外)
{
//忽略
}
}
}
Task.WaitAll(operations.ToArray());//最后,这将等待最后剩余的任务完成
}
私有静态异步任务GetDocument(int documentId)
{
等待任务;
尝试
{
GoGetDocument(文档ID);
}
捕获(例外)
{
//忽略
}
最后
{
_threadManager.Release();//任务完成时释放信号量
}
}
.Join?你在读什么样的帖子?(添加到你的研究结果的链接将有助于了解你到底需要什么帮助)你是否考虑过类似于Parallel.ForEach(DocumentId,new ParallelOptions{MaxDegreeOfParallelism=5},processDocumentId)的内置功能
?我不知道这里如何调用DoStuff或在哪里调用DoStuff?也不确定DoGetDocument来自何处或它应该做什么…提供的示例中是否缺少代码?还有,您的GetDocument()方法应该通过查看方法签名返回任务,但您没有返回方法中的任何内容…它不应该是一个完整的正在运行的应用程序。它旨在演示如何实现多线程。
static class Program
{
private const int _maxWorkers = 10;
private static readonly SemaphoreSlim _threadManager = new SemaphoreSlim(_maxWorkers);
private void DoStuff()
{
var queue = new ConcurrentQueue<int>(SomeClass.GetDocumentIds());
var operations = new List<Task>();
while (!queue.IsEmpty)
{
int documentId;
if (queue.TryDequeue(out documentId))
{
_threadManager.Wait(); // this will block after max number of threads is met
try
{
operations.Add(GetDocument(documentId);
}
catch (Exception)
{
// ignored
}
}
}
Task.WaitAll(operations.ToArray()); // finally, this waits till the last remaining tasks are complete
}
private static async Task GetDocument(int documentId)
{
await Task.Yield();
try
{
GoGetDocument(documentId);
}
catch (Exception)
{
// ignored
}
finally
{
_threadManager.Release(); // release the semaphore when the task completes
}
}