如何制作等待响应最多 30 秒的定时对话



我试图在 C# 中围绕线程进行思考,但我在实现此行为时遇到困难。

我需要一个简单的是/否对话框,当经过 30 秒时返回DialogResult.No

到目前为止,我得到的是:

Thread th = new Thread(() =>
{
    try
    {
        result = message.ShowDialog();
    }
    catch (Exception)
    {
    }
});
th.Start();
Thread.Sleep(30000);
th.Abort();

当我在对话框中选择"是"或"否"时,它仍然等待 30 秒,我需要线程在收到响应时停止。

这可能是一个不费吹灰之力的事情,但我对 C# 相对较新,并且确实可以在这方面使用一些帮助。

您可以在初始化表单时使用计时器。计时器过期后,关闭表单。

Timer time1 = new Timer();
time1.Elapsed += new ElapsedEventHandler(OnTimedEvent);
time1.Interval = 30000; // 30 secs
...
time1.Enabled = true; // Start the timer
message.ShowDialog();
private void OnTimedEvent(object source, ElapsedEventArgs e)
{
    // Close your Form
    message.Close();
    // Maybe you could set a variable, that indicates you, that the timer timed out
}

你必须覆盖ShowDialog()ShowDialog(owner)。当调用显示对话框时,您启动一个计时器并转发到base.ShowDialog()。当计时器引发tick事件时,只需调用Close()即可。

下面是一个示例实现:

public partial class FormTimed : Form
{
    private String _OriginalText;
    private DateTime _StartTime;
    private Timer _Timer;
    public FormTimed()
    {
        InitializeComponent();
        InitializeTimer();
        Duration = TimeSpan.FromSeconds(10);
    }
    [DefaultValue(typeof(TimeSpan), "00:00:10")]
    public TimeSpan Duration { get; set; }
    public override string Text
    {
        get
        {
            return _OriginalText;
        }
        set
        {
            _OriginalText = value;
            base.Text = value;
        }
    }
    public void DisableTimer()
    {
        _Timer.Stop();
        base.Text = _OriginalText;
    }
    public void ResetTimer()
    {
        _StartTime = DateTime.UtcNow;
        _Timer.Start();
    }
    public new DialogResult ShowDialog()
    {
        StartTimer();
        return base.ShowDialog();
    }
    public new DialogResult ShowDialog(IWin32Window owner)
    {
        StartTimer();
        return base.ShowDialog(owner);
    }
    private void InitializeTimer()
    {
        _Timer = new Timer();
        _Timer.Interval = 100;
        _Timer.Tick += OnTimerTick;
    }
    private void OnTimerTick(object sender, EventArgs e)
    {
        var finishTime = _StartTime + Duration;
        var remainingDuration = finishTime - DateTime.UtcNow;
        if (remainingDuration < TimeSpan.Zero)
        {
            Close();
        }
        base.Text = _OriginalText + " (" + (int)remainingDuration.TotalSeconds + ")";
    }
    private void StartTimer()
    {
        _StartTime = DateTime.UtcNow;
        _Timer.Start();
    }
}

最新更新