C#多线程重复

标签 c# multithreading

我正在尝试制作一个工具,从我提供的许多 URL 中获取源字符串。我将这段代码用于多线程

new Thread(() =>
{
    while (stop != true)
    {
        if (nowworker >= threads)
        {
            Thread.Sleep(50);
        }
        else
        {
            if (i <= urllist.Count - 1)
            {
                var thread = new Thread(() =>
                {
                     string source = GetSource(urllist[i]);
                     SaveToFile(source, i + ".txt"); 
                });
                thread.Start();
                i++;
                nowworker += 1;
            }
            else
            {
                stop = true;
            }

        }
    }
}).Start();

它运行非常顺利,直到我检查结果并且有一些重复的结果并且缺少我提供的一些 url 如果对许多 url 使用更少的线程(10 线程 - 20 url)但是当对 20 url 使用 20 线程时没有问题。

请帮帮我。谢谢。

最佳答案

if (i <= urllist.Count - 1)
{
    var thread = new Thread(() =>
    {
         string source = GetSource(urllist[i]);
         SaveToFile(source, i + ".txt"); 
    });
    thread.Start();
    i++;
    nowworker += 1;
}

您传递给线程的方法不能保证在 i 更新(i++)之前执行。事实上,不太可能。这意味着多个线程可能使用相同的 i 值,而 i 的某些值不会有任何线程执行它。

更糟糕的是,GetSource 可能使用与 SaveToFile 不同的 i 值。

在这里阅读:http://jonskeet.uk/csharp/csharp2/delegates.html

这将解决它:

if (i <= urllist.Count - 1)
{
    var currentIndex = i;
    var thread = new Thread(() =>
    {
         string source = GetSource(urllist[currentIndex]);
         SaveToFile(source, currentIndex + ".txt"); 
    });
    thread.Start();
    i++;
    nowworker += 1;
}

更好的是,您可以将整个代码块替换为:

Parallel.For(0, urlList.Count - 1, 
    new ParallelOptions { MaxDegreeOfParallelism = threads }, 
    i =>
    {       
        string source = GetSource(urllist[i]);
        SaveToFile(source, i + ".txt");
    }
);

这将摆脱代码臭味 Thread.Sleep() 并让 .NET 为您管理旋转线程

关于C#多线程重复,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32643451/

相关文章:

c# - 构建动态表达式树时出现问题

multithreading - 多个读者同步,单个作者?

c# - Kentico 7 - 在 web 部件中显示媒体库中的图像

linux - 是否有可能知道当前线程获得了多少 CPU 使用率?

c# - 如何处理在 BackgroundWorker 中运行的方法的状态

c - pthreads并行化错误结果

php - 通过同时进行的Cron作业下载电子邮件附件-竞赛条件

c# - IE 添加 http header PRAGMA : no-cache

c# - 如何为 ASP.NET MVC 5 应用程序设置时区?

c# - 手动发布到 Asp.Net MVC Controller