Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Task.Factory.StartNew isn';I don’我没料到会这样_C#_Multithreading_Parallel Processing_Task Parallel Library_Task - Fatal编程技术网

C# Task.Factory.StartNew isn';I don’我没料到会这样

C# Task.Factory.StartNew isn';I don’我没料到会这样,c#,multithreading,parallel-processing,task-parallel-library,task,C#,Multithreading,Parallel Processing,Task Parallel Library,Task,我一直在尝试确定与其余代码并发/并行运行代码的最佳方式,可能是使用线程。据我所知,使用线程类型在现代C#中是一个禁忌。起初我以为Parallel.Invoke(),但结果却是一个阻塞调用,直到所有内部工作完成 在我的应用程序中,我不需要等待任何事情完成,我不关心得到结果,我需要完全独立于当前线程的代码。基本上是一个“开火然后忘记”的想法。 据我所知,Task.Factory.StartNew()是与当前运行的代码并行运行代码的正确方法 基于此,我认为下面的代码会随机打印出“abababaa” v

我一直在尝试确定与其余代码并发/并行运行代码的最佳方式,可能是使用线程。据我所知,使用
线程
类型在现代C#中是一个禁忌。起初我以为
Parallel.Invoke()
,但结果却是一个阻塞调用,直到所有内部工作完成

在我的应用程序中,我不需要等待任何事情完成,我不关心得到结果,我需要完全独立于当前线程的代码。基本上是一个“开火然后忘记”的想法。

据我所知,
Task.Factory.StartNew()
是与当前运行的代码并行运行代码的正确方法

基于此,我认为下面的代码会随机打印出“abababaa”

void Main()
{
Task.Factory.StartNew(()=>
{
对于(int i=0;i<10;i++)
{
控制台。写入(“A”);
}
});
对于(int i=0;i<10;i++)
{
控制台。写入(“B”);
}
}
然而,它:

  • 打印出“bbbbbbaaaaaaaa”
  • 如果我将Task.Factory.StartNew与的
    交换,反之亦然,则会打印出相同的序列,这似乎很奇怪
  • 因此,这让我想到
    Task.Factory.StartNew()
    实际上从来没有将工作安排到另一个线程,就好像调用
    StartNew
    是一个阻塞调用一样

    考虑到我不需要获得任何结果或等待/
    等待
    的要求,我是否更容易创建一个新的
    线程
    并在那里运行代码?我唯一的问题是使用
    线程
    似乎与现代最佳实践背道而驰,《C#6.0中的并发性》一书指出:

    只要您键入new Thread(),它就结束了;您的项目已经有遗留代码


    实际上Task.Factory.StartNew确实在单独的线程上运行。它每次都会失败的唯一原因是因为任务创建时间。下面是证明它的代码

    static void Main(string[] args)
        {
            Task.Factory.StartNew(() =>
            {
                for (int i = 0; i < 10; i++)
                {
                    Console.Write("A");
                    Thread.Sleep(1);
                }
            });
    
            for (int i = 0; i < 10; i++)
            {
                Console.Write("B");
                Thread.Sleep(1);
            }
            Console.ReadKey();
        }
    
    static void Main(字符串[]args)
    {
    Task.Factory.StartNew(()=>
    {
    对于(int i=0;i<10;i++)
    {
    控制台。写入(“A”);
    睡眠(1);
    }
    });
    对于(int i=0;i<10;i++)
    {
    控制台。写入(“B”);
    睡眠(1);
    }
    Console.ReadKey();
    }
    
    实际上Task.Factory.StartNew确实在单独的线程上运行。它每次都会失去竞争的唯一原因是因为任务创建时间。下面是证明它的代码

    static void Main(string[] args)
        {
            Task.Factory.StartNew(() =>
            {
                for (int i = 0; i < 10; i++)
                {
                    Console.Write("A");
                    Thread.Sleep(1);
                }
            });
    
            for (int i = 0; i < 10; i++)
            {
                Console.Write("B");
                Thread.Sleep(1);
            }
            Console.ReadKey();
        }
    
    static void Main(字符串[]args)
    {
    Task.Factory.StartNew(()=>
    {
    对于(int i=0;i<10;i++)
    {
    控制台。写入(“A”);
    睡眠(1);
    }
    });
    对于(int i=0;i<10;i++)
    {
    控制台。写入(“B”);
    睡眠(1);
    }
    Console.ReadKey();
    }
    
    在我的应用程序中,我不需要等待任何事情完成,我不关心得到结果,我需要完全独立于当前线程的代码。基本上是一个“开火然后忘记”的想法

    你确定吗?Fire and forget的真正意思是“我完全可以忽略异常”。因为这不是大多数人想要的,一种常见的方法是将工作排队,保存一个表示该工作的任务,并在程序执行任何操作的“结束”时加入它,只是为了确保“不太火而忘”的工作能够成功完成

    我一直在尝试确定与其余代码并发/并行运行代码的最佳方式,可能是使用线程。据我所知,使用线程类型在现代C#中是一个禁忌。起初我认为是Parallel.Invoke(),但事实证明这是一个阻塞调用,直到所有内部工作完成

    则并行代码将阻止调用线程。这可以通过将并行调用包装在
    任务中来避免。运行
    (如我书中的配方7.4所示)

    在您的特定情况下(即,在火灾和遗忘场景中),您只需放下
    等待
    ,然后执行一个简单的
    任务。运行
    。虽然正如我上面提到的,最好还是把
    任务
    藏到某个地方,然后等待它

    据我所知,Task.Factory.StartNew()是与当前运行的代码并发/并行运行代码的正确方法

    不,只能作为最后手段使用。正确的技术是
    Task.Run
    ,如果您有真正的并行工作要做(即,许多CPU绑定的代码块),那么
    Task.Run
    包装
    parallel
    /plink将是最好的

    基于此,我认为下面的代码会随机打印出“abababaa”

    因为,这只是一个比赛条件。将工作排入线程池需要时间,计算机可以很快数到10。(写入输出要慢得多,但在这里还是太快了)。同样的问题也会出现在
    任务中。运行
    (或手动
    线程

    在我的应用程序中,我不需要等待任何事情完成,我不关心得到结果,我需要完全独立于当前线程的代码。基本上是一个“开火然后忘记”的想法

    你确定吗?Fire and forget的真正意思是“我完全可以忽略异常”。因为这不是大多数人想要的,一种常见的方法是将工作排队,保存一个表示该工作的任务,并在程序执行任何操作的“结束”时加入它,只是为了确保“不太火而忘”的工作能够成功完成

    我一直在努力确定并发/并行运行代码的最佳方式