简体   繁体   English

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

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

Is it possible to make sure that a task runs on another thread than the main thread? 是否可以确保任务在主线程之外的另一个线程上运行? So that this piece of code would not bock the calling thread? 所以这段代码不会打扰调用线程?

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

I know that there is Task.Delay but I want to make sure that the task will run on another thread. 我知道有Task.Delay但我想确保该任务将在另一个线程上运行。

I think that there are different ways to accomplish what you are trying. 我认为有不同的方法可以实现你的目标。 But based on what you are trying to do, I think that you would be fine just using async/await which is not going to block your UI for sure, and will allow you to control your task asynchronously. 但是根据你想要做的事情,我认为你可以使用async / await,这不会阻止你的用户界面,并且可以让你以异步方式控制你的任务。

As MSDN says: 正如MSDN所说:

Async methods are intended to be non-blocking operations. 异步方法旨在实现非阻塞操作。 An await expression in an async method doesn't block the current thread while the awaited task is running. 在等待任务运行时,异步方法中的await表达式不会阻止当前线程。 Instead, the expression signs up the rest of the method as a continuation and returns control to the caller of the async method. 相反,表达式将方法的其余部分作为延续进行注册,并将控制权返回给异步方法的调用者。 The async and await keywords don't cause additional threads to be created. async和await关键字不会导致创建其他线程。 Async methods don't require multithreading because an async method doesn't run on its own thread. 异步方法不需要多线程,因为异步方法不能在自己的线程上运行。 The method runs on the current synchronization context and uses time on the thread only when the method is active. 该方法在当前同步上下文上运行,并仅在方法处于活动状态时在线程上使用时间。 You can use Task.Run to move CPU-bound work to a background thread, but a background thread doesn't help with a process that's just waiting for results to become available. 您可以使用Task.Run将CPU绑定的工作移动到后台线程,但后台线程无助于只等待结果可用的进程。

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

This is an example of usage: 这是一个用法示例:

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;
}

This won´t block your UI 这不会阻止您的UI

@Nico is correct in that ideally, you could use asynchronous programming all the way. @Nico是正确的,理想情况下,你可以一直使用异步编程。 That approach is ideal because it doesn't waste a thread sleeping (or, in a more realistic example, blocking on I/O). 这种方法是理想的,因为它不会浪费线程休眠(或者,更实际的例子,阻止I / O)。

Is it possible to make sure that a task runs on another thread than the main thread? 是否可以确保任务在主线程之外的另一个线程上运行?

Yes. 是。 Task.Run will always queue work to the thread pool, and the main (entry point) thread is never a thread pool thread. Task.Run将始终将工作排队到线程池,而主(入口点)线程永远不是线程池线程。

Use the thread pool. 使用线程池。

    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();
    }

The output should look like this: 输出应如下所示: 在此输入图像描述

Your current code should work, but you will need to call the Start() method on the task to invoke it. 您当前的代码应该可以工作,但是您需要在任务上调用Start()方法来调用它。

You could also accomplish this through threading: 您也可以通过线程实现此目的:

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

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

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