Async/Await avec un WinForms ProgressBar

J'ai eu ce type de chose, travaillant dans le passé avec un BackgroundWorker, mais je veux profiter de la nouvelle async/await approche de .NET 4.5. J'ai peut-être aboiements le mauvais arbre. Veuillez informer.

Objectif: Créer un composant qui vont faire de longs et afficher un formulaire modal avec une barre de progression comme il fait le travail. Le composant va obtenir le handle d'une fenêtre pour bloquer l'interaction alors que c'est l'exécution de l'œuvre.

Statut: Voir le code ci-dessous. J'ai pensé que j'allais bien jusqu'à ce que j'ai essayé d'interagir avec windows. Si je laisse les choses seul (c'est à dire de ne pas y toucher!), tout fonctionne "parfaitement", mais si je le fais autant que de cliquer sur la fenêtre du programme se bloque au bout de la longue course de travail se termine. Réelles interactions (glisser) sont ignorées, comme si le thread d'INTERFACE utilisateur est bloqué.

Questions: Puis mon code fixe assez facilement? Si oui, comment? Ou, devrais-je utiliser une approche différente (par exemple, BackgroundWorker)?

Code (Form1 est un formulaire standard avec une ProgressBar et une méthode publique, UpdateProgress, qui définit le composant ProgressBar en Valeur):

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;
}
}
}
}
InformationsquelleAutor Todd Sprang | 2013-07-31