Tôi đã nhận được loại điều này làm việc trong quá khứ với một BackgroundWorker, nhưng tôi muốn sử dụng phương pháp tiếp cận async/await mới của .NET 4.5. Tôi có thể sủa cây sai. Xin cho biết.Async/Await with WinForms ProgressBar
Mục tiêu: Tạo thành phần sẽ thực hiện một số tác vụ dài và hiển thị biểu mẫu có thanh tiến trình khi đang thực hiện công việc. Các thành phần sẽ có được xử lý để một cửa sổ để ngăn chặn sự tương tác trong khi nó thực hiện công việc lâu dài.
Trạng thái: Xem mã bên dưới. Tôi nghĩ tôi đã làm tốt cho đến khi tôi thử tương tác với các cửa sổ. Nếu tôi để mọi thứ một mình (nghĩa là đừng chạm vào!), Mọi thứ sẽ chạy "hoàn hảo", nhưng nếu tôi làm như vậy thì nhấp vào một trong hai cửa sổ chương trình sẽ bị treo sau khi kết thúc công việc dài hạn. Tương tác thực tế (kéo) bị bỏ qua như thể chuỗi giao diện người dùng bị chặn.
Câu hỏi: Mã của tôi có thể được sửa dễ dàng không? Nếu vậy, làm thế nào? Hoặc, tôi có nên sử dụng một cách tiếp cận khác (ví dụ: BackgroundWorker) không?
Mã (Form1 là một hình thức tiêu chuẩn với một ProgressBar và một phương pháp công cộng, UpdateProgress, mà bộ giá trị gia tăng của ProgressBar):
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;
}
}
}
}
nếu Go (tiến trình) ném một ngoại lệ, sau đó _progressForm.Close() sẽ không bao giờ được gọi -> hộp thoại phương thức sẽ treo mãi mãi – Hiep
Và tốt hơn nên thay đổi "_progressForm.Activated" thành "_progressForm .Shown" vì _progressForm có thể được kích hoạt nhiều lần trong suốt cuộc đời của mình .. -> Go (tiến trình) sẽ được gọi nhiều lần .. – Hiep
https://gist.github.com/duongphuhiep/f83f98593d93045e717f – Hiep