これまでは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(進行)が例外をスローした場合、_progressForm.Close()は呼び出されません - >モーダルダイアログが永久にハングします – Hiep
そして_progressFormがアクティブになる可能性があるため、 "_progressForm.Activated"を "彼の人生の時間中に複数回。 - >行く(進行)は複数回呼び出されます.. – Hiep
https://gist.github.com/duongphuhiep/f83f98593d93045e717f – Hiep