代码之家  ›  专栏  ›  技术社区  ›  Davorin

线程同步作业

  •  2
  • Davorin  · 技术社区  · 15 年前

    有一个包含100个字符串uri的字符串数组mydownloadList。我想启动5个线程作业,这些作业将从MyDownloadList(如堆栈)中弹出下一个URI,并对其执行一些操作(下载它),直到堆栈上没有剩余的URI(MyDownloadList)。

    这样做的最佳实践是什么?

    2 回复  |  直到 15 年前
        1
  •  6
  •   Reed Copsey    15 年前

    使用 ThreadPool ,只需设置所有请求。线程池将自动适当地调度它们。

    使用.NET 4,使用任务并行库会更容易。将每个请求设置为 Task 是非常有效和容易。

        2
  •  1
  •   David Basarab    15 年前

    确保每个线程在访问MyDownloadList时都锁定它。您可以使用递归来获取最新的一个,然后当列表为0时,它可以停止函数。

    请参见下面的示例。

    public static List<string> MyList { get; set; }
    public static object LockObject { get; set; }
    
    static void Main(string[] args)
    {
        Console.Clear();
    
        Program.LockObject = new object();
    
        // Create the list
        Program.MyList = new List<string>();
    
        // Add 100 items to it
        for (int i = 0; i < 100; i++)
        {
            Program.MyList.Add(string.Format("Item Number = {0}", i));
        }
    
        // Start Threads
        for (int i = 0; i < 5; i++)
        {
            Thread thread = new Thread(new ThreadStart(Program.PopItemFromStackAndPrint));
    
            thread.Name = string.Format("Thread # {0}", i);
    
            thread.Start();
        }
    } 
    
    
    public static void PopItemFromStackAndPrint()
    {
        if (Program.MyList.Count == 0)
        {
            return;
        }
    
        string item = string.Empty;
    
        lock (Program.LockObject)
        {
            // Get first Item
            item = Program.MyList[0];
    
            Program.MyList.RemoveAt(0);
        }
    
        Console.WriteLine("{0}:{1}", System.Threading.Thread.CurrentThread.Name, item);
    
        // Sleep to show other processing for examples only
        System.Threading.Thread.Sleep(10);
    
        Program.PopItemFromStackAndPrint();
    }