Code should be executed one time after short delay

天大地大妈咪最大 提交于 2019-12-22 07:41:05

问题


I have this Timer:

Timer delayTimer = new Timer();
delayTimer.Interval = 500;
delayTimer.Elapsed += (object sender, ElapsedEventArgs e) => {
    Console.WriteLine("test");
    textInputDialog.Show();
    delayTimer.Stop();
};
delayTimer.Start();

Here I have the following problems:

  • Timer never stops. Code is executed every 500ms.
  • textInputDialog.Show(); doesn't work (perhaps cause of problem above)

What is wrong with my code?

Alternative solutions:

This is an alternative to timer as Jens Horstmann mentioned. And this is called on the UI thread:

private async Task SendWithDelay()
{
    await Task.Delay(500);
    textInputDialog.Show();
}

Another alternative would be NSTimer:

NSTimer.CreateScheduledTimer(new TimeSpan(0,0,0,0,500), delegate {
    textInputDialog.Show();
});

And to invoke a call on the UI thread you can use InvokeOnMainThread:

Timer delayTimer = new Timer();
delayTimer.Interval = 500;
delayTimer.Elapsed += (object sender, ElapsedEventArgs e) => {
    delayTimer.Stop();
    Console.WriteLine("test");
    InvokeOnMainThread (() => {
        textInputDialog.Show();
    });
};
delayTimer.Start();

回答1:


Stop the timer before you show the dialog:

delayTimer.Elapsed += (object sender, ElapsedEventArgs e) => {
    delayTimer.Stop();
    Console.WriteLine("test");
    textInputDialog.Show();
};

Also you probably used the wrong timer. Don't use System.Threading.Timer or System.Timers because this involves multithreading which does not work well with winforms or WPF. (This is probably the reason your MessageBox does not show - its called on the wrong thread)

In WPF you should use System.Windows.Threading.DispatcherTimer

Edit

In Winforms you should use System.Windows.Forms.Timer (see comments)




回答2:


Here is a solution without async/await

It also happen to fit in a single statement, which is rather elegant.
This is a C#, cross-platform solution to perform an action after a delay. Also works for a recurring task.

using System.Threading;

var delayTimer = new Timer((state) => // Create timer, forget about it
    InvokeOnMainThread(() =>          // Fire on main thread
        textInputDialog.Show()        // Your code goes here
    ),
    null,                             // Ignore the state
    5 * 1000,                         // 5 seconds until the 1st fire
    Timeout.Infinite);                // Do not repeat



回答3:


Something like this worked for me:

    private async Task DelayedShow()
    {
        await Task.Delay(500);
        await _loadPop.textInputDialog.Show();
    }

Remember to call the method like this:

  BeginInvokeOnMainThread(() => DelayedShow());


来源:https://stackoverflow.com/questions/28168694/code-should-be-executed-one-time-after-short-delay

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!