【发布时间】:2015-07-27 05:16:51
【问题描述】:
我试过了
Parallel.Invoke(() => Method1(), () => Method2());
同时启动 Method1 和 Method2 操作。但只有 Method1 正在执行。请问有什么解决办法。
继续this,我添加了以下代码。
class Program
{
static void Main(string[] args)
{
CancellationTokenSource cts = new CancellationTokenSource();
Task.Factory.StartNew(() => { Thread.Sleep(5000); cts.Cancel(); });
ProcessFiles(cts.Token);
Console.ReadKey();
}
public static void ProcessFiles(CancellationToken cts)
{
try
{
LimitedConcurrencyLevelTaskScheduler lcts = new LimitedConcurrencyLevelTaskScheduler(2);
List<Task> tasks = new List<Task>();
TaskFactory factory = new TaskFactory(lcts);
Parallel.Invoke(
() => Method1(cts, tasks, factory),
() => Method2(cts, tasks, factory));
Task.WaitAll(tasks.Where(t => t != null).ToArray());
Console.WriteLine("\n\nSuccessful completion.");
Console.ReadLine();
}
catch (AggregateException aex)
{
// Ignore
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
private static void Method1(CancellationToken cts, List<Task> tasks, TaskFactory factory)
{
for (int i = 0; i < 1000; i++)
{
int i1 = i;
var t = factory.StartNew(() =>
{
Console.WriteLine("Method 1 --- {0} --- {1}", i1, GetGuid());
}, cts);
tasks.Add(t);
}
}
private static void Method2(CancellationToken cts, List<Task> tasks, TaskFactory factory)
{
for (int i = 0; i < 1000; i++)
{
int i1 = i;
var t = factory.StartNew(() =>
{
Console.WriteLine("Method 2 --- {0} --- {1}", i1, GetGuid());
}, cts);
tasks.Add(t);
}
}
private static Guid GetGuid()
{
Thread.Sleep(TimeSpan.FromSeconds(1));
return Guid.NewGuid();
}
}
O/P:只有 Method1 正在调用。方法2不是。
【问题讨论】:
-
方法 1 在方法 2 有机会之前排队一堆任务。然后,您甚至在方法 2 任务开始之前就超时了。在
factory.StartNew()之前放置一些 Console.WriteLines(或 Thread.Sleep()),它会引入足够的延迟,让您看到方法 2 的混入。 -
Rob 是正确的 - 但还有一些其他问题。另外,查看 Task.Delay 并注意将 cts 与 null 进行比较是不正确的(它是一个结构 - 它永远不会为 null) - 你可能是指类似 cts.ThrowIfCancellationRequested
-
添加 Console.WriteLines(或 Thread.Sleep())后,我可以看到这两种方法的执行。谢谢
-
请注意,同时运行 Method1() 和 Method2() 会在“tasks.Add(t)”行引入竞争条件,因为类 List
不是线程安全的。
标签: c# asp.net multithreading linq