Я использовал этот тип работы в прошлом с BackgroundWorker, но я хочу использовать новый подход async/wait для .NET 4.5. Я могу лаять неправильное дерево. Просьба сообщить.
Цель: создать компонент, который будет выполнять некоторую длительную работу и показать модальную форму с индикатором выполнения, выполняя работу. Компонент получит дескриптор окна для блокировки взаимодействия при выполнении долговременной работы.
Статус: см. код ниже. Я думал, что у меня все хорошо, пока я не попытался взаимодействовать с окнами. Если я оставляю вещи в покое (то есть не трогаю!), Все работает "отлично", но если я делаю так много, как нажимать на любое окно, программа зависает после завершения длительной работы. Фактические взаимодействия (перетаскивание) игнорируются, как если бы поток пользовательского интерфейса блокировался.
Вопросы. Может ли мой код исправляться довольно легко? Если да, то как? Или, должен ли я использовать другой подход (например, BackgroundWorker)?
Код (Form1 - стандартная форма с ProgressBar и общедоступный метод UpdateProgress, который устанавливает значение 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;
}
}
}
}