Best way to name a single operation in the future?

I want to disable the timer, which needs to be executed once at some point in the future. I want to use a lambda expression for brevity. So I want to do something like ...

(new System.Threading.Timer(() => { DoSomething(); },
                    null,  // no state required
                    TimeSpan.FromSeconds(x), // Do it in x seconds
                    TimeSpan.FromMilliseconds(-1)); // don't repeat

I think this is pretty neat. But in this case, the Timer object is not deleted. What is the best way to fix this? Or should I do a completely different approach here?

+3
source share
7 answers

This will accomplish what you want, but I'm not sure if this is the best solution. I think this is something short and elegant, but can be more confusing and difficult to accomplish than its value.

System.Threading.Timer timer = null;
timer = new System.Threading.Timer(
    (object state) => { DoSomething(); timer.Dispose(); }
    , null // no state required
    ,TimeSpan.FromSeconds(x) // Do it in x seconds
    ,TimeSpan.FromMilliseconds(-1)); // don't repeat
+4
source

.
. , . , , .

, , .

static void Main(string[] args)
{
    DoThing();
    GC.Collect();
    Thread.Sleep(5000);
}


static void DoThing()
{
    new System.Threading.Timer(x => { Console.WriteLine("Here"); },
            null,  
            TimeSpan.FromSeconds(1), 
            TimeSpan.FromMilliseconds(-1));
}
+3

...

class Program
{
    static void Main(string[] args)
    {
        MyTimer.Create(
            () => { Console.WriteLine("hello"); },
            5000);
        GC.Collect();
        GC.WaitForPendingFinalizers();
        Console.Read();
    }
}
public class MyTimer
{
    private MyTimer() { }
    private Timer _timer;
    private ManualResetEvent _mre;

    public static void Create(Action action, int dueTime)
    {
        var timer = new MyTimer();
        timer._mre = new ManualResetEvent(false);

        timer._timer = new Timer(
            (x) =>
            {
                action();
                timer._mre.Set();
            },
            null,
            dueTime,
            Timeout.Infinite
            );

        new Thread(new ThreadStart(() =>
        {
            timer._mre.WaitOne();
            timer._timer.Dispose();
        })).Start();
    }
}
+1

:

bool fired = false;

ThreadPool.RegisterWaitForSingleObject(new ManualResetEvent(false), 
    (state, triggered) =>
    {
        fired = true;
    }, 
    0, 9000, true);

GC.Collect();

Thread.Sleep(10000);

Assert.IsTrue(fired);

, -.

+1

, , . .

, . , , , , .

0

(Dispatcher), :

    void MyNonAsyncFunction()
    {
        Dispatcher.InvokeAsync(async () =>
        {
            await Task.Delay(1000);
            MessageBox.Show("Thank you for waiting");
        });
    }

, . , , , , :

    async void MyAsyncFunction()
    {
        // Do my other things

        await Task.Delay(1000);
        MessageBox.Show("Thank you for waiting");
    }

, .

Since you may not have a dispatcher or you want to use it, but still want to schedule several operations at different times, I would use a thread:

    static void MyFunction()
    {
        // Do other things...
        Schedule(1000, delegate
        {
            System.Diagnostics.Debug.WriteLine("Thanks for waiting");
        });
    }

    static void Schedule(int delayMs, Action action)
    {
#if DONT_USE_THREADPOOL
        // If use of threadpool is undesired:
        new System.Threading.Thread(async () =>
        {
            await Task.Delay(delayMs);
            action();
        }
        ).Start(); // No need to store the thread object, just fire and forget
#else
        // Using the threadpool:
        Task.Run(async delegate
        {
            await Task.Delay(delayMs);
            action();
        });
#endif
    }

If you want to avoid async, I would recommend not using threadpool and replacing the call with a Task.Delay(delayMs)callThread.Sleep(delayMs)

0
source
          System.Reactive.Linq.Observable.Interval(TimeSpan.FromSeconds(1))
            .FirstAsync()
            .Subscribe(_ => DoSomething()));
-2
source

Source: https://habr.com/ru/post/1720122/


All Articles