我正在学习任务和异步方法。 但是为什么线程如何比我的例子中的任务更快。 看起来async方法没有并发运行,但我的线程肯定是并发运行的。
以下是任务的代码。
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace ConsoleApplication25
{
using System.Diagnostics;
using System.Threading;
class Program
{
static void Main(string[] args)
{
var watch = Stopwatch.StartNew();
watch.Start();
Task.Run(
async () =>
{
var ts = new CancellationTokenSource();
CancellationToken ct = ts.Token;
List<Task> myTasks = new List<Task>();
try
{
for (int i = 0; i < 10; i++)
{
myTasks.Add(Print(i, ts));
}
await Task.WhenAll(myTasks);
// Task.WaitAll(myTasks.ToArray());
}
catch (OperationCanceledException ex1)
{
Console.Write("here" + ex1);
}
catch (Exception ex2)
{
Console.Write("bye" + ex2);
}
}).GetAwaiter().GetResult();
watch.Stop();
Console.WriteLine("total tasks = " + watch.ElapsedMilliseconds );
var watch2 = Stopwatch.StartNew();
watch2.Start();
List<Thread> ThreadList = new List<Thread>();
for (int i = 0; i < 10; i++)
{
Thread newThread = new Thread(ThreadPrint);
ThreadList.Add(newThread);
newThread.Start(i);
}
foreach (var mythread in ThreadList)
{
mythread.Join();
}
watch2.Stop();
Console.WriteLine("total thread= " + watch2.ElapsedMilliseconds);
}
public static async Task Print(int id, CancellationTokenSource ts)
{
var watch = Stopwatch.StartNew();
watch.Start();
int counter = 0;
while (true)
{
counter ++;
// Console.WriteLine(Thread.CurrentThread.ManagedThreadId + "Loop " + id + ":::::" + "count = " + counter + "last =" + watch.ElapsedMilliseconds);
if (counter == 200000000)
{
watch.Stop();
Console.WriteLine(Thread.CurrentThread.ManagedThreadId + "EXIT " + id + ":::::" + "count = " + counter + "last =" + watch.ElapsedMilliseconds);
break;
}
// Console.WriteLine(Thread.CurrentThread.ManagedThreadId + "here it is " + id + ":::::" + "count = " + counter);
}
}
public static void ThreadPrint(object id)
{
var watch = Stopwatch.StartNew();
watch.Start();
int counter = 0;
while (true)
{
//Thread.Sleep(100);
counter++;
// Console.WriteLine(Thread.CurrentThread.ManagedThreadId + "Loop " + id + ":::::" + "count = " + counter + "last =" + watch.ElapsedMilliseconds);
if (counter == 200000000)
{
watch.Stop();
Console.WriteLine(Thread.CurrentThread.ManagedThreadId + "EXIT " + (int)id + ":::::" + "count = " + counter + "last =" + watch.ElapsedMilliseconds);
break;
}
// Console.WriteLine(Thread.CurrentThread.ManagedThreadId + "here it is " + id + ":::::" + "count = " + counter);
}
}
}
}
答案 0 :(得分:1)
您的代码不正确
您的Print方法实际上是同步的。
因此,如果是任务,您可以创建单个任务并按顺序运行Print调用。
正确的方法是将调用包装到每个Print而不是整个循环。
myTasks.Add(Task.Run(()=>Print(i, ts));