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)
Task.Delay改为使用:
await Task.Delay(5000);
Run Code Online (Sandbox Code Playgroud)
因为Thread.Sleep实际上阻塞了当前线程,所以不应该在异步方法中使用.
你可以在这里找到更多相关信息:何时使用Task.Delay,何时使用Thread.Sleep?