0

如果这是一个简单的问题,我很抱歉,但我非常疲惫,虽然思考得直。我最近设置了线程并且它工作得很好。用户选择要对其执行工作的项目,我Thread为他们选择的项目动态创建一个 s 数组,并为每个项目调度一个线程。

但是,我注意到如果选择太多,则文件所在的服务器不会播放得很好。我知道一个事实,我一次只能声明 5 个活动线程,即使有 30 个项目需要工作,但我无法理解它。

PS:如果我描述 ThreadPool 让我知道......我试图让它工作,但有一段时间没有运气,对 .NET 的线程方式很新。

当前方式:

threadedResults = new List<string>[SelectedItems.Count];
List<string> results = new List<string>();
ThreadSettings tsArgs = (ThreadSettings)args;

for (int i = 0; i < SelectedItems.Count; i++)
{
    threadedResults[i] = new List<string>();
}

Thread[] threads = new Thread[SelectedItems.Count];

for (int i = 0; i < SelectedItems.Count; i++)
{
    KeyValuePair<int, ThreadSettings> threadArgs = new KeyValuePair<int, ThreadSettings>(i, (ThreadSettings)tsArgs);

    threads[i] = new Thread(new ParameterizedThreadStart(DoWork));
    threads[i].Start(threadArgs);
}
for (int i = 0; i < SelectedItems.Count; i++)
{
    if (CommandTask != null)
        threads[i].Join();
    else
    {
        // User Cancelled, abort all threads and break
        for (int j = 0; j < SelectedItems.Count; j++)
        {
            threads[j].Abort();
        }
        break;
    }
}

// Gather all results, format and return
4

2 回答 2

2

基本上,你会想在 TPL 中做这样的事情:

        // source for cancelling work
        var cxlSource = new CancellationTokenSource();

        // create and schedule tasks to start
        var tasks =
            Enumerable.Range(0, SelectedItems.Count)
                .Select(i => Task.Factory.StartNew(DoWork, yourStateInfo, cxlSource.Token))
                .ToArray();

        // then wait for the results
        Task.WaitAll(tasks);

如果在任何时候,您需要取消任务,您可以请求取消:

            cxlSource.Cancel();

这将阻止任何等待执行的任务开始,并且您的任务可以定期检查令牌本身,以便如果在进行中被取消,它们可以提前中止。

使用 TPL(以及一般的线程)有很多细微差别,但这是一个粗略的想法。

于 2012-06-06T16:02:09.927 回答
1

如果你想坚持你的版本,我会声明 Environment.ProcessorCount 线程数,而不是 5(如果你有 2 个处理器,5 个线程中只有 2 个将同时运行)。线程过多会导致系统开销(这可能是您的问题)。

如果没有,请考虑在 .net 4 或 TreadPool 中使用 Task。

于 2012-06-06T15:56:34.070 回答