繁体   English   中英

如何使用Thread.Sleep与Task.Run而不阻止主踏板

[英]How to use Thread.Sleep with Task.Run without blocking main tread

是否可以确保任务在主线程之外的另一个线程上运行? 所以这段代码不会打扰调用线程?

var task = Task.Run(() =>
{
    //third party code i don't have access to
    Thread.Sleep(3000);
});

我知道有Task.Delay但我想确保该任务将在另一个线程上运行。

我认为有不同的方法可以实现你的目标。 但是根据你想要做的事情,我认为你可以使用async / await,这不会阻止你的用户界面,并且可以让你以异步方式控制你的任务。

正如MSDN所说:

异步方法旨在实现非阻塞操作。 在等待任务运行时,异步方法中的await表达式不会阻止当前线程。 相反,表达式将方法的其余部分作为延续进行注册,并将控制权返回给异步方法的调用者。 async和await关键字不会导致创建其他线程。 异步方法不需要多线程,因为异步方法不能在自己的线程上运行。 该方法在当前同步上下文上运行,并仅在方法处于活动状态时在线程上使用时间。 您可以使用Task.Run将CPU绑定的工作移动到后台线程,但后台线程无助于只等待结果可用的进程。

https://msdn.microsoft.com/en-us/library/mt674882.aspx

这是一个用法示例:

public async Task MyMethodAsync()
{
    Task<int> runTask = RunOperationAsync();

    int result = await longRunningTask;

    Console.WriteLine(result);
}

public async Task<int> RunOperationAsync()
{
    await Task.Delay(1000); //1 seconds delay
    return 1;
}

这不会阻止您的UI

@Nico是正确的,理想情况下,你可以一直使用异步编程。 这种方法是理想的,因为它不会浪费线程休眠(或者,更实际的例子,阻止I / O)。

是否可以确保任务在主线程之外的另一个线程上运行?

是。 Task.Run将始终将工作排队到线程池,而主(入口点)线程永远不是线程池线程。

使用线程池。

    static void Main(string[] args)
    {
        ThreadPool.QueueUserWorkItem(o => { Thread.Sleep(5000); Console.WriteLine("Threadpool task done."); });
        for( int i = 0; i < 10; i++)
        {
            Console.WriteLine("Main thread: {0}", i);
            Thread.Sleep(1000);
        }

        Console.ReadLine();
    }

输出应如下所示: 在此输入图像描述

您当前的代码应该可以工作,但是您需要在任务上调用Start()方法来调用它。

您也可以通过线程实现此目的:

new System.Threading.Thread(() => {
    System.Threading.Thread.Sleep(500);
}).Start();

暂无
暂无

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

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