Delayed function calls

后端 未结 12 1271
星月不相逢
星月不相逢 2020-11-30 22:07

Is there a nice simple method of delaying a function call whilst letting the thread continue executing?

e.g.

public void foo()
{
    // Do stuff!

           


        
相关标签:
12条回答
  • 2020-11-30 22:31

    It sounds like the control of the creation of both these objects and their interdependence needs to controlled externally, rather than between the classes themselves.

    0 讨论(0)
  • 2020-11-30 22:31

    It's indeed a very bad design, let alone singleton by itself is bad design.

    However, if you really do need to delay execution, here's what you may do:

    BackgroundWorker barInvoker = new BackgroundWorker();
    barInvoker.DoWork += delegate
        {
            Thread.Sleep(TimeSpan.FromSeconds(1));
            bar();
        };
    barInvoker.RunWorkerAsync();
    

    This will, however, invoke bar() on a separate thread. If you need to call bar() in the original thread you might need to move bar() invocation to RunWorkerCompleted handler or do a bit of hacking with SynchronizationContext.

    0 讨论(0)
  • 2020-11-30 22:33

    Thanks to modern C# 5/6 :)

    public void foo()
    {
        Task.Delay(1000).ContinueWith(t=> bar());
    }
    
    public void bar()
    {
        // do stuff
    }
    
    0 讨论(0)
  • 2020-11-30 22:34

    There is no standard way to delay a call to a function other than to use a timer and events.

    This sounds like the GUI anti pattern of delaying a call to a method so that you can be sure the form has finished laying out. Not a good idea.

    0 讨论(0)
  • 2020-11-30 22:39
    public static class DelayedDelegate
    {
    
        static Timer runDelegates;
        static Dictionary<MethodInvoker, DateTime> delayedDelegates = new Dictionary<MethodInvoker, DateTime>();
    
        static DelayedDelegate()
        {
    
            runDelegates = new Timer();
            runDelegates.Interval = 250;
            runDelegates.Tick += RunDelegates;
            runDelegates.Enabled = true;
    
        }
    
        public static void Add(MethodInvoker method, int delay)
        {
    
            delayedDelegates.Add(method, DateTime.Now + TimeSpan.FromSeconds(delay));
    
        }
    
        static void RunDelegates(object sender, EventArgs e)
        {
    
            List<MethodInvoker> removeDelegates = new List<MethodInvoker>();
    
            foreach (MethodInvoker method in delayedDelegates.Keys)
            {
    
                if (DateTime.Now >= delayedDelegates[method])
                {
                    method();
                    removeDelegates.Add(method);
                }
    
            }
    
            foreach (MethodInvoker method in removeDelegates)
            {
    
                delayedDelegates.Remove(method);
    
            }
    
    
        }
    
    }
    

    Usage:

    DelayedDelegate.Add(MyMethod,5);
    
    void MyMethod()
    {
         MessageBox.Show("5 Seconds Later!");
    }
    
    0 讨论(0)
  • 2020-11-30 22:41

    This will work either on older versions of .NET
    Cons: will execute in its own thread

    class CancelableDelay
        {
            Thread delayTh;
            Action action;
            int ms;
    
            public static CancelableDelay StartAfter(int milliseconds, Action action)
            {
                CancelableDelay result = new CancelableDelay() { ms = milliseconds };
                result.action = action;
                result.delayTh = new Thread(result.Delay);
                result.delayTh.Start();
                return result;
            }
    
            private CancelableDelay() { }
    
            void Delay()
            {
                try
                {
                    Thread.Sleep(ms);
                    action.Invoke();
                }
                catch (ThreadAbortException)
                { }
            }
    
            public void Cancel() => delayTh.Abort();
    
        }
    

    Usage:

    var job = CancelableDelay.StartAfter(1000, () => { WorkAfter1sec(); });  
    job.Cancel(); //to cancel the delayed job
    
    0 讨论(0)
提交回复
热议问题