簡體   English   中英

C#中的線程同步

[英]Thread synchronization in C#

在我的應用程序中,我使用不同的線程(每個活動傳輸一個)。 例如,我想限制活動的轉移,將其他即將到來的轉移入隊列。

現在,我的解決方案是檢查是否有空間進行另一個活動傳輸,否則,我會將請求放入隊列列表中。 每當我完成一個活動時,我都會從隊列中選擇一個。 (但我想我的解決方案真的很臟)

有沒有計划活動線程的好方法?

使用信號燈是不錯的選擇嗎?

您可以使用BlockingCollection來管理隊列,例如:

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;

namespace Demo
{
    public class Program
    {
        private readonly BlockingCollection<int> _queue = new BlockingCollection<int>();

        private void run()
        {
            const int CONSUMER_COUNT = 8;

            Task[] tasks = new Task[CONSUMER_COUNT];

            for (int i = 0; i < CONSUMER_COUNT; ++i)
            {
                int id = i;
                tasks[i] = Task.Run(() => process(id));
            }

            Console.WriteLine("Press <return> to start adding to the queue.");
            Console.ReadLine();

            for (int i = 0; i < 100; ++i)
            {
                Console.WriteLine("Adding item #{0}", i);
                _queue.Add(i);
            }

            Console.WriteLine("Press <return> to close the queue.");
            Console.ReadLine();

            _queue.CompleteAdding();

            Console.WriteLine("Waiting for all tasks to exit.");
            Task.WaitAll(tasks);

            Console.WriteLine("Finished waiting for all tasks. Press <return> to exit.");
            Console.ReadLine();
        }

        private void process(int id)
        {
            Console.WriteLine("Process {0} is starting.", id);

            foreach (var item in _queue.GetConsumingEnumerable())
            {
                Console.WriteLine("Process {0} is processing item# {1}", id, item);
                Thread.Sleep(200); // Simulate long processing time.
            }

            Console.WriteLine("Process {0} is stopping.", id);
        }

        private static void Main()
        {
            new Program().run();
        }
    }
}

請注意,這里的關鍵是GetConsumingEnumerable()返回一個枚舉,如果隊列中沒有任何項目,它將阻塞,但是如果沒有項目並且生產者調用了CompleteAdding() ,它將退出。 這使得控制工作線程何時退出非常容易。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM