繁体   English   中英

如何创建一个内部带有等待方法的线程?

[英]How to create a thread with await methods inside?

我正在创建一个线程

Thread MyThread = new Thread(async () => await MyTask());
MyThread.Start(); 

这有点没有意义,这就是如何正确创建它的问题。

MyTask 是一个无休止的任务,它会定期启动 CPU 密集型工作

async Task MyTask ()
    {
        while (true)
        {                
            await Task.Run(() => CPU_Load());
            await Task.Delay(1000).ConfigureAwait(false);
        }
    }

CPU_Load 是一种正在完成工作的方法

void CPU_Load ()
    {            
       *CPU_Load*    
    }


      

当 Main 不能异步时,原始的异步策略怎么样。 使用非异步 function(或委托或 lambda)启动您的线程。 在那个 function 中,简单地说 WhatIWantToDoAsync().Wait(); 那是异步的并返回一个任务。 您的线程 function 永远不会返回,所以等待它不会做太多。 – Flydog57

Thread构造函数不理解async委托。 你可以在这里阅读:

定期执行某些代码的“正确”方式取决于您要在哪里运行代码。 你有什么理由在专用线程上运行它吗? 一些组件是线程仿射的,并且在它们存在的整个过程中都需要由同一线程操作。 如果你有这个(不是很常见的)需求,你可以使用没有 async/await 的Thread构造函数:

var myThread = new Thread(() =>
{
    while (true)
    {
        var delayTask = Task.Delay(1000);
        CPU_Load();
        delayTask.Wait();
    }
});
myThread.IsBackground = true;
myThread.Start();

注意Task.Delay任务是如何在 CPU-bound 操作之前创建的,然后在之后等待。 这样, CPU_Load方法的两次后续调用之间的间隔将保持不变。 它不取决于通话本身的持续时间。

如果您不需要专用线程,则可以通过使用ThreadPool中的可重用线程来更经济地完成工作。 这正是您当前的MyTask实现所做的,其中包含Task.Run方法。 启动任务就像调用异步方法一样简单:

var myTask = MyTask();

现在任务正在运行,并将继续运行直到进程终止,或者CPU_Load调用失败,无论先发生什么。

实现异步MyTask方法的另一种方法是将整个循环包装在Task.Run中,而不是将Task.Run放在循环中。 在功能和性能方面几乎相同:

var myTask = Task.Run(async () =>
{
    while (true)
    {
        var delayTask = Task.Delay(1000);
        CPU_Load();
        await delayTask;
    }
});

我省略了ConfigureAwait(false) ,因为它并不是真正需要的。 ThreadPool没有可被await捕获的同步上下文。

您也可以考虑使用Timer定期运行您的工作,但我认为基于Task的方法更好。 使用Timer强制执行具有恒定间隔的非重叠执行策略非常棘手。 注意事项:

  1. System.Timers.Timer class 不是线程安全的。
  2. 它允许事件处理程序的重叠调用。
  3. 它吞下处理程序中抛出的任何异常。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM