入力フォームのStephen Clearyで問題を解決できました。更新3を参照してください。スレッドタイマーで非同期/待機しています
私は、非同期修飾子を持つメソッドを持つWindowsフォームアプリケーションを持っています。メソッドがボタンのクリックイベント内で呼び出された場合、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);
}
アップデート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);
}
しかし、私はまだ同じ問題があります。シャットダウンstfはタイマーコールバックの内側で呼び出されるとブロックされます。メインのUIは大丈夫です。それに問題はない。私は、シャットダウン(stf)GUIがタイマーコールバックから作成されたときに応答するようにしたいだけです。シャットダウンGUIには進行状況バーがあります。
アップデート3:Thread.Sleep
ので
await Task.Delay(5000);
実際ブロック現在のスレッドおよび非同期メソッド内で使用すべきではない。ここで
が最終コード
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();
}
こんにちは@stephenはあなたの入力に感謝します。元の投稿を更新しました。上記をご覧ください。どのUIがフリーズしているのか正しく言っていないかもしれません。 – IamaC
@IamaC:同じ答えが適用されます。バックグラウンドスレッドからUIコードを実行しないでください。 –
ありがとう@stephen。私はあなたの意見で問題を解決することができました。アップデート3をご覧ください – IamaC