Как поставить задачу на сон (или задержку) в C # 4.0?

Существует Task.Delay в .NET 4.5

Как я могу сделать то же самое в .NET 4.0?

67 голосов | спросил Fulproof 11 MarpmMon, 11 Mar 2013 19:06:49 +04002013-03-11T19:06:49+04:0007 2013, 19:06:49

9 ответов


0

Вы можете использовать Timer для создания Delay метод в 4.0:

public static Task Delay(double milliseconds)
{
    var tcs = new TaskCompletionSource<bool>();
    System.Timers.Timer timer = new System.Timers.Timer();
    timer.Elapsed+=(obj, args) =>
    {
        tcs.TrySetResult(true);
    };
    timer.Interval = milliseconds;
    timer.AutoReset = false;
    timer.Start();
    return tcs.Task;
}
ответил Servy 11 MarpmMon, 11 Mar 2013 19:20:56 +04002013-03-11T19:20:56+04:0007 2013, 19:20:56
0

Используйте Microsoft.Bcl.Async из NuGet, в нем есть TaskEx.Delay

ответил Eli Arbel 12 MarpmTue, 12 Mar 2013 13:12:38 +04002013-03-12T13:12:38+04:0001 2013, 13:12:38
0
using System;
using System.Threading;
using System.Threading.Tasks;

class Program
{
    static void Main()
    {
        Delay(2000).ContinueWith(_ => Console.WriteLine("Done"));
        Console.Read();
    }

    static Task Delay(int milliseconds)
    {
        var tcs = new TaskCompletionSource<object>();
        new Timer(_ => tcs.SetResult(null)).Change(milliseconds, -1);
        return tcs.Task;
    }
}

Из раздела Как реализовать Task.Delay в 4.0

ответил QrystaL 11 MarpmMon, 11 Mar 2013 19:14:28 +04002013-03-11T19:14:28+04:0007 2013, 19:14:28
0

Ниже приведен код и пример использования для отменяемой реализации Task.Delay. Вы, вероятно, заинтересованы в методе Delay.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DelayImplementation
{
    class Program
    {
        static void Main(string[] args)
        {
            System.Threading.CancellationTokenSource tcs = new System.Threading.CancellationTokenSource();

            int id = 1;
            Console.WriteLine(string.Format("Starting new delay task {0}. This one will be cancelled.", id));
            Task delayTask = Delay(8000, tcs.Token);
            HandleTask(delayTask, id);

            System.Threading.Thread.Sleep(2000);
            tcs.Cancel();

            id = 2;
            System.Threading.CancellationTokenSource tcs2 = new System.Threading.CancellationTokenSource();
            Console.WriteLine(string.Format("Starting delay task {0}. This one will NOT be cancelled.", id));
            var delayTask2 = Delay(4000, tcs2.Token);
            HandleTask(delayTask2, id);

            System.Console.ReadLine();
        }

        private static void HandleTask(Task delayTask, int id)
        {
            delayTask.ContinueWith(p => Console.WriteLine(string.Format("Task {0} was cancelled.", id)), TaskContinuationOptions.OnlyOnCanceled);
            delayTask.ContinueWith(p => Console.WriteLine(string.Format("Task {0} was completed.", id)), TaskContinuationOptions.OnlyOnRanToCompletion);
        }

        static Task Delay(int delayTime, System.Threading.CancellationToken token)
        {
            TaskCompletionSource<object> tcs = new TaskCompletionSource<object>();

            if (delayTime < 0) throw new ArgumentOutOfRangeException("Delay time cannot be under 0");

            System.Threading.Timer timer = null;
            timer = new System.Threading.Timer(p =>
            {
                timer.Dispose(); //stop the timer
                tcs.TrySetResult(null); //timer expired, attempt to move task to the completed state.
            }, null, delayTime, System.Threading.Timeout.Infinite);

            token.Register(() =>
                {
                    timer.Dispose(); //stop the timer
                    tcs.TrySetCanceled(); //attempt to mode task to canceled state
                });

            return tcs.Task;
        }
    }
}
ответил Gusdor 26 FebruaryEurope/MoscowbWed, 26 Feb 2014 15:57:36 +0400000000pmWed, 26 Feb 2014 15:57:36 +040014 2014, 15:57:36
0

Расширяя идею этого ответа :

new AutoResetEvent(false).WaitOne(1000);
ответил Alex R. 7 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowThu, 07 Sep 2017 06:47:18 +0300 2017, 06:47:18
0

Во многих случаях явное AutoResetEvent лучше, чем Thread.Sleep () ...

AutoResetEvent pause = new AutoResetEvent(false);
Task timeout = Task.Factory.StartNew(()=>{
pause.WaitOne(1000, true);
});

надеюсь, что это поможет

ответил f.capet 1 stEurope/Moscowp30Europe/Moscow09bEurope/MoscowTue, 01 Sep 2015 16:20:01 +0300 2015, 16:20:01
0

Вы можете загрузить Visual Studio Async CTP и использовать TaskEx.Delay

ответил DVD 12 MaramTue, 12 Mar 2013 00:43:51 +04002013-03-12T00:43:51+04:0012 2013, 00:43:51
0
    public static void DelayExecute(double delay, Action actionToExecute)
    {
        if (actionToExecute != null)
        {
            var timer = new DispatcherTimer
            {
                Interval = TimeSpan.FromMilliseconds(delay)
            };
            timer.Tick += (delegate
            {
                timer.Stop();
                actionToExecute();
            });
            timer.Start();
        }
    }
ответил WndRnr 26 +03002016-10-26T22:02:45+03:00312016bEurope/MoscowWed, 26 Oct 2016 22:02:45 +0300 2016, 22:02:45
0

Вот краткая, основанная на таймере реализация с надлежащей очисткой:

var wait = new TaskCompletionSource<bool>();
using (new Timer(_ => wait.SetResult(false), null, delay, Timeout.Infinite))
    await wait.Task;

Чтобы использовать этот код в .NET 4.0, вам нужен Microsoft.Bcl. Async пакет NuGet.

ответил Edward Brey 26 FebruaryEurope/MoscowbSun, 26 Feb 2017 18:10:42 +0300000000pmSun, 26 Feb 2017 18:10:42 +030017 2017, 18:10:42

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132