【问题标题】:Parallel.Invoke is executing first method onlyParallel.Invoke 仅执行第一个方法
【发布时间】:2015-07-27 05:16:51
【问题描述】:

我试过了

Parallel.Invoke(() => Method1(), () => Method2());

同时启动 Method1Method2 操作。但只有 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


【解决方案1】:

在 factory.StartNew() 之前添加 Console.WriteLines(或 Thread.Sleep())后,我可以看到这两种方法都在执行。

感谢 Rob 的解决方案

【讨论】:

    猜你喜欢
    • 2018-05-29
    • 1970-01-01
    • 1970-01-01
    • 2017-06-22
    • 2012-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多