async/await with thread timer

Iam*_*maC -1 c# asynchronous timer winforms

我能够通过输入表单Stephen Cleary解决问题.请参阅更新3.

我有一个Windows窗体应用程序,其中包含一个带有async修饰符的方法.如果在按钮的click事件中调用该方法,则它不会阻止UI线程.但是,当我在计时器内调用它作为回调时,它会冻结UI.我无法弄清楚我在这里做错了什么.请看下面我的代码.这只是一个用于演示目的的示例项目.

public Form1()
{
    InitializeComponent();            
}

private async void formCloseAsync()
{
    shutdown stf = new shutdown();
    stf.StartPosition = FormStartPosition.CenterScreen;
    stf.Show();
    var task = Task.Factory.StartNew(processClose);
    await task;
}

private void processClose()
{
    Thread.Sleep(5000);
    Environment.Exit(1);
}

private void simpleButtonAsync_Click(object sender, EventArgs e)
{
    formCloseAsync();
}        

private void _simpleButtonTimer_Click(object sender, EventArgs e)
{
    Timer _shutdownTimer = new Timer(delegate
    {
       formCloseAsync();
    }, null, 5000, Timeout.Infinite);
}
Run Code Online (Sandbox Code Playgroud)

更新1:谢谢大家的宝贵意见.请参阅下面的更新代码

public Form1()
    {
        InitializeComponent();

    }

    private Timer _shutdownTimer;
    private void formCloseAsync()
    {
        shutdown stf = new shutdown();
        stf.StartPosition = FormStartPosition.CenterScreen;
        stf.Show();

        Task.Run(async ()=>
            { 
                await Task.Delay(5000);
                Environment.Exit(1);
            }
        );
    }

    private void simpleButtonAsync_Click(object sender, EventArgs e)
    {
        formCloseAsync();
    }

    private void _simpleButtonTimer_Click(object sender, EventArgs e)
    {
        _shutdownTimer = new Timer(async delegate
        {
            formCloseAsync();
        }, null, 0, Timeout.Infinite);
    }
Run Code Online (Sandbox Code Playgroud)

但是我仍然有同样的问题.在计时器回调中调用时,shutdown stf被阻止.主UI是好的.没问题.我只是希望关闭(stf)GUI在从定时器回调创建时响应.关闭GUI有一个进度条.

更新3:

这是最终的代码

public partial class Form1 : Form
{
    readonly shutdown _stf = new shutdown();
    public Form1()
    {
        InitializeComponent();

    }

    private Timer _shutdownTimer;
    private async Task formCloseAsync()
    {

        try
        {
            BeginInvoke(new MethodInvoker(delegate
            {

                _stf.StartPosition = FormStartPosition.CenterScreen;
                _stf.Show();
            }));
            await Task.Run( async () =>
                            {
                                await Task.Delay(5000);
                            });

        }
        catch (Exception ex)
        {

            MessageBox.Show(ex.ToString());

        }
        finally
        {
            Environment.Exit(1);
        }

    }

    private  void simpleButtonAsync_Click(object sender, EventArgs e)
    {
        formCloseAsync();
    }

    private void _simpleButtonTimer_Click(object sender, EventArgs e)
    {
        _shutdownTimer = new Timer(async delegate
        {
            formCloseAsync();
        }, null, 0, Timeout.Infinite);
    }

    private async void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
        e.Cancel = true;
         await formCloseAsync();
    }
Run Code Online (Sandbox Code Playgroud)

The*_*One 5

Task.Delay改为使用:

await Task.Delay(5000);
Run Code Online (Sandbox Code Playgroud)

因为Thread.Sleep实际上阻​​塞了当前线程,所以不应该在异步方法中使用.

你可以在这里找到更多相关信息:何时使用Task.Delay,何时使用Thread.Sleep?

  • 睡眠是从后台线程调用的,所以这不是他的问题.他应该改变它,但这不会导致他声称自己遇到的问题. (3认同)