我试图异步显示一个进度表单,表明应用程序正在运行,而实际应用程序正在运行。
如下这个问题 https://stackoverflow.com/questions/33406939/async-showdialog,我有以下内容:
主要形式:
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
async Task<int> LoadDataAsync()
{
await Task.Delay(2000);
return 42;
}
private async void Run_Click(object sender, EventArgs e)
{
var runningForm = new RunningForm();
runningForm.ShowRunning();
var progressFormTask = runningForm.ShowDialogAsync();
var data = await LoadDataAsync();
runningForm.Close();
await progressFormTask;
MessageBox.Show(data.ToString());
}
}
进度表
public partial class RunningForm : Form
{
private readonly SynchronizationContext synchronizationContext;
public RunningForm()
{
InitializeComponent();
synchronizationContext = SynchronizationContext.Current;
}
public async void ShowRunning()
{
this.RunningLabel.Text = "Running";
int dots = 0;
await Task.Run(() =>
{
while (true)
{
UpadateUi($"Running{new string('.', dots)}");
Thread.Sleep(300);
dots = (dots == 3) ? 0 : dots + 1;
}
});
}
public void UpadateUi(string text)
{
synchronizationContext.Post(
new SendOrPostCallback(o =>
{
this.RunningLabel.Text = text;
}),
text);
}
public void CloseThread()
{
synchronizationContext.Post(
new SendOrPostCallback(o =>
{
this.Close();
}),
null);
}
}
internal static class DialogExt
{
public static async Task<DialogResult> ShowDialogAsync(this Form form)
{
await Task.Yield();
if (form.IsDisposed)
{
return DialogResult.OK;
}
return form.ShowDialog();
}
}
上面的工作正常,但当我从另一个地方打电话时,它不起作用。这是我的控制台应用程序:
class Program
{
static void Main(string[] args)
{
new Test().Run();
Console.ReadLine();
}
}
class Test
{
private RunningForm runningForm;
public async void Run()
{
var runningForm = new RunningForm();
runningForm.ShowRunning();
var progressFormTask = runningForm.ShowDialogAsync();
var data = await LoadDataAsync();
runningForm.CloseThread();
await progressFormTask;
MessageBox.Show(data.ToString());
}
async Task<int> LoadDataAsync()
{
await Task.Delay(2000);
return 42;
}
}
观察调试器发生的情况,进程开始await Task.Yield()
并且永远不会进展到return form.ShowDialog()
因此你永远不会看到RunningForm
。然后该过程转到LoadDataAsync()
并永远挂在await Task.Delay(2000)
.
为什么会发生这种情况?和怎么做有关系吗Task
s 具有优先级(即:Task.Yield() https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.yield?view=netframework-4.7.2)?