同一方法中的ThreadPool异步线程

时间:2011-04-13 11:36:30

标签: c# multithreading asynchronous threadpool

我有一个关于ThreadPool用法的问题。 我运行简单的下面的代码后。我得到了结果:

  • ID:6 - > A
  • ID:13 - > A
  • ID:6 - > 2A
  • ID:12 - > A
  • ID:13 - > 2A
  • ID:15 - > A
  • ID:6 - >图3A
  • ID:12 - > 2A
  • ID:14 - > A
  • ID:13 - >图3A

(这继续...) 这是我的代码:

static void Main(string[] args)
{
    Program p = new Program();
    p.Start();
    Console.ReadLine();
}

private void Start()
{
    System.Timers.Timer senderTimer;
    senderTimer = new System.Timers.Timer();
    senderTimer.Elapsed += new System.Timers.ElapsedEventHandler(SenderTimer);
    senderTimer.Interval = 500;
    senderTimer.Enabled = true;
}

private void SenderTimer(object Source, ElapsedEventArgs e)
{
    ThreadPool.QueueUserWorkItem(new WaitCallback(Foo));
}

private void Foo(object state)
{
    string[] array = new string[] { "A", "2A", "3A", "4A", "5A", "6A", "7A", "8A", "9A", "10A" };

    for (int i = 0; i < array.Length; i++)
    {
        Trace.WriteLine("ID : " + Thread.CurrentThread.GetHashCode() + " --> " + array[i]);
        Thread.Sleep(1000); // Here I have a DB Operation, so i make it sleep
    }
}

我需要得到的结果是多个线程执行相同的操作。 这是我必须得到的输出:希望我清楚地解释。有没有办法做到这一点?

  • ID:6 - &gt; A
  • ID:13 - &gt; 2A
  • ID:6 - &gt;图3A
  • ID:12 - &gt;图4A
  • ID:13 - &gt;图5A
  • ID:15 - &gt;图6A
  • ID:6 - &gt;图7A
  • ID:12 - &gt;图8A
  • ID:14 - &gt;图9A
  • ID:13 - &gt;图10A

感谢任何帮助。非常感谢。

2 个答案:

答案 0 :(得分:1)

如果你想强制处理顺序那么就没有必要让它成为多线程,因为每个线程都会等待前一个线程。

如果您想要并行处理,然后按照收到的顺序排列结果,那么您可以使用

        string[] array = new string[] { "A", "2A", "3A", "4A", "5A", "6A", "7A", "8A", "9A", "10A" };
        var results = array.AsParallel().Select((item, i) =>
        new
        {
            Index = i,
            Result = ProcessItem(item)
        })
        .OrderBy(x => x.Index)
        .Select(i=>i.Result)
        .ToList();

答案 1 :(得分:0)

您应该在Foo函数之外打印数字数组。如果它在里面,每个线程将尝试处理完整列表,但这不是你想要的(据我所知)。

你想创建一个新函数,比如说GetNextItemToProcess将返回尚未处理的数组中的下一个项目。然后,在您的Foo函数中,调用类似

的内容
lock(this)
{
   string nextItem = GetNextItemToProcess();
   Trace.WriteLine("ID : " + Thread.CurrentThread.GetHashCode() + " --> " + nextItem );
}

由于每个线程都需要确保正确抓取下一个项目,因此需要锁定。重要说明:锁定整个功能,同时确保您想要的,不利于多线程。使用这种方法,它可能也是串行的。如果每个工作项都可以以任意顺序执行,线程将真正给你带来好处,而这不是这里的情况。如果你真的需要输出“A,2A,3A”,你最好连续进行。如果它可以是“2A,A,3A”或随机顺序,其中每个项目预计只出现一次,则线程就是你想要的。