在同一时间内同时执行相同的多任务操作。

6
我在Asp.net C#中遇到了问题。
我有以下代码: List objectList = new List();
foreach(var item in listItem)
{
  object obj = getData (item);
  objectList.add(obj);
}
Console.Write("Finish all");

每次`getData(item);`触发需要大约1秒钟的时间; 我希望在`foreach`完成后执行`Console.write("Finish all")`之前,`listItem`中的所有项都能同时运行。 我该如何做到呢? 感谢您提供任何想法!

1
在单独的线程中调用函数? - KMC
这就像是在说:我不会向你展示如何优化某个东西,这不是一个真正的问题。为什么运行aaa()需要1秒钟? - Mitch Wheat
1
@MitchWheat 但我认为他的问题是正确的,aaa()内部发生了什么并不重要,他不想优化aaa(),他想要一些并行解决方案,这是一个很好的问题。 - Mahdi Tahsildari
@MitchWheat aaa()只需1秒钟,它是最好的,很抱歉我不能在这里分享aaa()的功能,还有,感谢您的帮助。 - Lex Nguyen
aaa() 我想从服务器获取项目(超出控制),但服务器响应速度太慢。之后我将该项目添加到另一个列表中。 - Lex Nguyen
4个回答

5

您可以使用Task完成此操作:

 var tasks = listItem.Select(item => Task.Factory.StartNew(() => aaa()));
 Task.WaitAll(tasks.ToArray());

 Console.Write();

如果您不需要等待所有任务完成,只需跳过WaitAll
 var tasks = listItem.Select(item => Task.Factory.StartNew(() => aaa()));
 Console.Write();

对于 .NET 3.5,您可以使用线程池(ThreadPool):

 listItem.ForEach(item => ThreadPool.QueueUserWorkItem(state => aaa()));
 Console.Write();

我正在使用 .net 3.5,有其他方法吗?因为 Task 只适用于 .net 4。 - Lex Nguyen
状态 => aaa(); "state" 是什么?我尝试了但出错了。 aaa() 像这样做: {object obj = "这需要1秒钟"; objectList.add(obj);} - Lex Nguyen
状态 => aaa(),我认为状态尚未定义。 - Lex Nguyen

5
 using System.Threading;
 using System.Threading.Tasks;

 List<Task> tasks = new List<Task>();
 foreach(item in listItem)
 {
       tasks.Add(Task.Factory.StartNew(() => aaa()));
 }
// If you want the Console.Writeline to execute immediately after starting the tasks
Console.Writeline();            
Task.WaitAll(tasks.ToArray());
Console.Writeline("Finised executing all tasks");


如果你想使用线程来完成这个任务,可以这样做:

List<ManualResetEvent> resetEvents = new List<ManualResetEvent>();
.
.
.


 foreach(item in lisItem)
            {
                Thread thread = new Thread(new ParameterizedThreadStart(aaa));
                ManualResetEvent resetEvent = new ManualResetEvent(false);
                resetEvents.Add(resetEvent);
                thread.Start(resetEvent);

            }
            Console.WriteLine();
            WaitHandle.WaitAll(resetEvents.ToArray<WaitHandle>());
            Console.WriteLine("Finised executing all threads");


        }

}
.
.
.

    void aaa(object data)
    {
        ManualResetEvent resetEvent = data as ManualResetEvent;
        // completed execution
        Console.WriteLine(".");
        resetEvent.Set();
    }

使用 System.Threading.Tasks; 我找不到 Threading.Tasks,是什么问题? - Lex Nguyen
我使用的是.NET 3.5,有其他方法吗?因为Task仅适用于.NET 4。 - Lex Nguyen
首先,非常感谢您的帮助。但是我还不太清楚。抱歉,因为我是新手。aaa()函数只有两行代码: object obj = "This take 1second"; objectList.add(obj);那么,我该如何使用您的代码呢?希望您能再次帮助我。非常感谢! - Lex Nguyen

5

这将给使代码线程安全增加重大负担(就像这里提出的任何其他多线程建议一样),并且对同一服务器的其他请求产生未知影响。 - Alexei Levenkov
我正在使用 .NET 3.5,Parallel 不存在。 - Lex Nguyen

1
        int itemCount = ItemList.Count;

             List<object> objectList = new List<object>();
            ManualResetEvent[] resetEvents = new ManualResetEvent[itemCount];

            for (int i = 0; i < itemCount; i++)
            {

                var item= ItemList[i];

                resetEvents[i] = new ManualResetEvent(false);
                ThreadPool.QueueUserWorkItem(new WaitCallback((object index) =>
                {
                    ItemCalEvent item = getData(item);

                    lock (objectList)
                        objectList.Add(item);

                    resetEvents[(int)index].Set();
                }), i);
            }
            WaitHandle.WaitAll(resetEvents);

这在 .net 3.5 中很好。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接