Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/322.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# 为什么;Console.Readline();占用5%的CPU,而;while(true)“;当试图保持线程打开时,需要30%的时间?_C#_Multithreading - Fatal编程技术网

C# 为什么;Console.Readline();占用5%的CPU,而;while(true)“;当试图保持线程打开时,需要30%的时间?

C# 为什么;Console.Readline();占用5%的CPU,而;while(true)“;当试图保持线程打开时,需要30%的时间?,c#,multithreading,C#,Multithreading,我正在我的机器上做这个测试。显然,cpu%会有所不同,但我更感兴趣的是了解发生了什么。 我只需创建一个新的、空白的控制台.Net Framework应用程序(--not--.NETCore)。 下面是“Program.cs”的来源: 那么这就是myClass的来源: class myClass { public async Task myInifiniteMethodAsync() { await Task.Run(() => myInfiniteMetho

我正在我的机器上做这个测试。显然,cpu%会有所不同,但我更感兴趣的是了解发生了什么。 我只需创建一个新的、空白的控制台.Net Framework应用程序(--not--.NETCore)。 下面是“Program.cs”的来源:

那么这就是myClass的来源:

class myClass
{
    public async Task myInifiniteMethodAsync()
    {
        await Task.Run(() => myInfiniteMethod());
    }
    public void myInfiniteMethod()
    {
        //do some things but keep this thread holded...

        //bool keepRunning = true;  
        //while (keepRunning)       {   } <--- this one takes 30% cpu...
        Console.ReadLine(); // <--- this one takes 5% cpu...
    }
}
class-myClass
{
公共异步任务myInifiniteMethodAsync()
{
等待任务。运行(()=>myInfiniteMethod());
}
公共无效myInfiniteMethod()
{
//做一些事情,但保持这个线程举行。。。
//bool-keepRunning=true;

//虽然(keepRunning){}为了回答您的问题,我们需要了解操作系统如何执行这些行

对于
while(true){}
,编译后的代码由变量
keepRunning
的比较组成,然后进行条件跳转。它的重要部分是操作系统连续执行指令

但是,对于
Console.ReadLine()
,它等待用户输入,操作系统只等待硬件中断(按键),而不需要连续执行指令

因此,循环版本要求操作系统为您的程序提供尽可能多的时间,因为它“想要”运行许多指令,而对于输入版本,操作系统只等待硬件中断,程序不需要执行任何其他指令。

好,至于“更好的方法”为了在低cpu消耗的情况下保持线程,我找到了一个答案:ManualResetEvent

而不是:

while (true); //or equivalent while (somevar)
现在我只做:

ManualResetEvent resetEvent = new ManualResetEvent(false);
resetEvent.WaitOne();       
无限方法的真正目的是什么?等待实现取决于它。但在大多数情况下,它是生产者-消费者编程模式。我建议,在这种情况下,它是全新的

下面是一个
BlockingCollection

static void Main(字符串[]args)
{
BlockingCollection消息=新建BlockingCollection();
消费者=新消费者(消息);
consumer.Start();
Console.WriteLine(“消费者启动”);
控制台写入线(“启动主循环(点击回车退出)”;
while(true)
{
字符串m=Console.ReadLine();
如果(m.长度>0)
添加(m);
其他的
打破
}
消费者。停止();
控制台写入线(“主循环完成”);
Console.ReadKey();
}
公共类消费者
{
私人封锁收集信息;
公共消费者(阻止收集消息)
{
_消息=消息;
}
私有void RunLoop()
{
Console.WriteLine(“启动使用者循环”);
foreach(在_messages.getconsumineGenumerable()中的字符串消息)//RunLoop();
}
公共停车场()
{
_messages.CompleteAdding();
}
}
以及输出

消费者启动
启动主循环(点击回车退出)
启动消费者循环
测试消息1
获取消息:测试消息1
喋喋不休
收到消息:布拉布拉
主回路已完成
消费者循环完成

这里不需要
async/await
,只需要一个
任务

好的,谢谢你的解释。我需要这个东西用于一个大型企业项目……在我看来,用“Console.Readline”发布一些东西太“不专业”了“要保持该线程…有没有更好的方法来获得相同的结果?您可以通过添加
线程来减少
while(true)
情况下的cpu使用量。Sleep
——即使是持续时间很短的线程——以防止持续时间过长execution@pinkfloydx33你说得对,加上一个简单的Thred.Sleep(1)在while(true)循环中,CPU的性能有很大的不同。无论如何,最后我更喜欢后来找到的manualresetevent解决方案,它看起来更“优雅”对我来说:-)它需要相同的cpu。这个答案也很有用。谢谢你,你的答案看起来很有趣,有很多新的东西需要我深入学习。在我的情况下,我需要“保持”企业应用程序中的Signal-R服务器集线器连接可以同时执行其他操作,因此我们的想法是使用异步运行它,并让它在单独的线程上运行。
ManualResetEvent resetEvent = new ManualResetEvent(false);
resetEvent.WaitOne();