c#多线程复制



我正在尝试制作一个工具,从我提供的许多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线程为20 url。

请帮帮我。谢谢你。

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为您管理旋转线程

最新更新