我有一个关于ThreadPool用法的问题。 我运行简单的下面的代码后。我得到了结果:
(这继续...) 这是我的代码:
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
}
}
我需要得到的结果是多个线程执行相同的操作。 这是我必须得到的输出:希望我清楚地解释。有没有办法做到这一点?
感谢任何帮助。非常感谢。
答案 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”或随机顺序,其中每个项目预计只出现一次,则线程就是你想要的。