我已经在BackgroundWorker中使用过这种类型的东西,但我想使用.NET 4.5的新异步/等待方法。我可能会吠叫错误的树。请指教。使用WinForms进行异步/等待ProgressBar
目标:创建一个组件,它将执行一些长时间运行的工作,并在进行工作时显示带有进度条的模态窗体。该组件将获取窗口的句柄,以在执行长时间运行的工作时阻止交互。
状态:请参阅下面的代码。我以为自己做得很好,直到我尝试与窗口交互。如果我把事情放在一边(即不要碰!),一切都会“完美地”运行,但是如果我点击任一窗口,程序就会在长时间运行结束后挂起。实际的交互(拖动)被忽略,就像UI线程被阻塞一样。
问题:我的代码可以很容易地修复吗?如果是这样,怎么样?或者,我应该使用其他方法(例如BackgroundWorker)吗?
代码(Form1上是一个标准的形式与进度和公共方法,的UpdateProgress中,设定进度的值):
using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Starting..");
var mgr = new Manager();
mgr.GoAsync();
Console.WriteLine("..Ended");
Console.ReadKey();
}
}
class Manager
{
private static Form1 _progressForm;
public async void GoAsync()
{
var owner = new Win32Window(Process.GetCurrentProcess().MainWindowHandle);
_progressForm = new Form1();
_progressForm.Show(owner);
await Go();
_progressForm.Hide();
}
private async Task<bool> Go()
{
var job = new LongJob();
job.OnProgress += job_OnProgress;
job.Spin();
return true;
}
void job_OnProgress(int percent)
{
_progressForm.UpdateProgress(percent);
}
}
class LongJob
{
public event Progressed OnProgress;
public delegate void Progressed(int percent);
public void Spin()
{
for (var i = 1; i <= 100; i++)
{
Thread.Sleep(25);
if (OnProgress != null)
{
OnProgress(i);
}
}
}
}
class Win32Window : IWin32Window
{
private readonly IntPtr _hwnd;
public Win32Window(IntPtr handle)
{
_hwnd = handle;
}
public IntPtr Handle
{
get
{
return _hwnd;
}
}
}
}
如果Go(progress)抛出一个异常,那么_progressForm.Close()永远不会被调用 - >模式对话框将永远挂起 – Hiep
并且最好将“_progressForm.Activated”更改为“_progressForm.Shown”,因为_progressForm可能被激活多次在他一生中的时间.. - >去(进展)将被称为多次.. – Hiep
https://gist.github.com/duongphuhiep/f83f98593d93045e717f – Hiep