简体   繁体   中英

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.

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.

As MSDN says:

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. 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 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.

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

@Nico is correct in that ideally, you could use asynchronous programming all the way. That approach is ideal because it doesn't waste a thread sleeping (or, in a more realistic example, blocking on 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.

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.

You could also accomplish this through threading:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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