Почему процесс теряет темы? - PullRequest
1 голос
/ 08 июля 2011

Вот код, который постоянно генерирует GUID. Я написал это, чтобы узнать о потоках. В нем вы заметите, что у меня есть блокировка, где я генерирую GUID и ставлю их в очередь, даже если ConcurrentQueue является поточно-ориентированным. Это потому, что мой настоящий код должен использовать NHibernate, и поэтому я должен убедиться, что только один поток получает заполнить очередь.

Пока я наблюдаю за этим кодом в диспетчере задач, я замечаю, что процесс уменьшает количество потоков с 18 (на моей машине) до 14, но не менее. Это потому, что мой код не очень хорош?

Также может ли кто-то рефакторинг этого, если сочтет нужным? Я люблю более короткий код.

class Program
{
    ConcurrentNewsBreaker Breaker;

    static void Main(string[] args)
    {
        new Program().Execute();

        Console.Read();
    }

    public void Execute()
    {
        Breaker = new ConcurrentNewsBreaker();
        QueueSome();
    }

    public void QueueSome()
    {
        ThreadPool.QueueUserWorkItem(DoExecute);
    }

    public void DoExecute(Object State)
    {
        String Id = Breaker.Pop();
        Console.WriteLine(String.Format("- {0} {1}", Thread.CurrentThread.ManagedThreadId, Breaker.Pop()));

        if (Breaker.Any())
            QueueSome();
        else
            Console.WriteLine(String.Format("- {0} XXXX ", Thread.CurrentThread.ManagedThreadId));            
    }
}


public class ConcurrentNewsBreaker
{
    static readonly Object LockObject = new Object();

    ConcurrentQueue<String> Store = new ConcurrentQueue<String>();

    public String Pop()
    {
        String Result = null;
        if (Any())
            Store.TryDequeue(out Result);
        return Result;
    }

    public Boolean Any()
    {
        if (!Store.Any())
        {
            Task FillTask = new Task(FillupTheQueue, Store);
            FillTask.Start();
            FillTask.Wait();
        }

        return Store.Any();
    }

    private void FillupTheQueue(Object StoreObject)
    {
        ConcurrentQueue<String> Store = StoreObject as ConcurrentQueue<String>;
        lock(LockObject)
        {
            for(Int32 i = 0; i < 100; i++)
                Store.Enqueue(Guid.NewGuid().ToString());            
        }
    }
}

Ответы [ 2 ]

2 голосов
/ 08 июля 2011

Вы используете .NET ThreadPool, поэтому .NET / Windows управляет количеством потоков на основе объема работы, ожидающей обработки.

1 голос
/ 08 июля 2011

Пока я отслеживаю этот код в Task Менеджер, я замечаю, что процесс падает количество нитей от 18 (по моему машина) до 14 но не меньше. Это потому что мой код не хорош?

Это не указывает на проблему. 14 все еще высоко, если у вас нет 16-ядерного процессора.

Пул потоков попытается настроить и выполнить работу с минимальным количеством потоков.

Вы должны начать беспокоиться, когда количество потоков значительно возрастет .

...