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”);
}
}
然而,它:
交换,反之亦然,则会打印出相同的序列,这似乎很奇怪
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的真正意思是“我完全可以忽略异常”。因为这不是大多数人想要的,一种常见的方法是将工作排队,保存一个表示该工作的任务,并在程序执行任何操作的“结束”时加入它,只是为了确保“不太火而忘”的工作能够成功完成
我一直在努力确定并发/并行运行代码的最佳方式