Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c#等待线程的多线程问题_C#_Multithreading - Fatal编程技术网

c#等待线程的多线程问题

c#等待线程的多线程问题,c#,multithreading,C#,Multithreading,在浏览了这个论坛上的许多帖子以及其他关于c#多线程的帖子之后,我仍然感到困惑,并且在处理这个问题时遇到了问题 我想创建numThreads线程数,以便为documentIds中的每个整数执行一个函数documentIds是一个计数为100的列表,我想在documentIds中的每个元素上调用resitchworker.resitch 我目前拥有的是以下内容,但我对如何保持5个线程在100个DocumentID列表中循环感到困惑。。。感谢所有的帮助 for (int i = 0; i < d

在浏览了这个论坛上的许多帖子以及其他关于c#多线程的帖子之后,我仍然感到困惑,并且在处理这个问题时遇到了问题

我想创建
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
            }

    }