@NDJ が投稿した内容は正しいです。何が起こっているかを示す簡単な例を作成しました。
まず、メソッド:
private static void TaskGestioneCartelle()
{
Task.Factory.StartNew(() => GeneraListaCartelle())
.ContinueWith(t => GeneraListaCartelleCompletata()
, CancellationToken.None
, TaskContinuationOptions.None
, TaskScheduler.FromCurrentSynchronizationContext());
}
private static void GeneraListaCartelle()
{
//No sleep could block the thread UI because the task is being executed on a different Thread
Debug.WriteLine("GeneraListaCartelle " + Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(4000);
mainForm.Invoke(new Action(() => bla.Text = "uno due tre, Genera Lista!"));
}
private static void GeneraListaCartelleCompletata()
{
//This is begin executed on the UI thread
Debug.WriteLine("GeneraListaCartelleCompletata " + Thread.CurrentThread.ManagedThreadId);
Task.Factory.StartNew(() => CopiaCartelle())
.ContinueWith(t => CopiaCartelleCompletato()
, CancellationToken.None
, TaskContinuationOptions.None
, TaskScheduler.FromCurrentSynchronizationContext());
}
private static void CopiaCartelle()
{
//This is begin executed on the UI thread (doesn't even show in the form 'cause the thread is blocked)
Debug.WriteLine("CopiaCartelle " + Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(4000);
mainForm.Invoke(new Action(() => bla.Text = "Copia Cartelle \\o"));
}
private static void CopiaCartelleCompletato()
{
//This is begin executed on the UI thread
Debug.WriteLine("CopiaCartelleCompletato " + Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(4000);
mainForm.Invoke(new Action(() => bla.Text = "Completato!"));
//Stops blocking the UI thread
}
フォームとコンポーネント
static Label bla = new Label()
{
Text = "Mama Mia, Gestione Cartelle!",
Left = 100,
Top = 100,
Width=300
};
static Label hangOn = new Label()
{
Text="Hang loose"
};
static Form mainForm = new Form()
{
Width = 600,
Height = 600
};
[STAThread]
static void Main(string[] args)
{
mainForm.Controls.Add(bla);
mainForm.Controls.Add(hangOn);
mainForm.MouseMove += (o, e) => { hangOn.Left = e.X; hangOn.Top = e.Y; };
Debug.WriteLine("UI Thread: "+ Thread.CurrentThread.ManagedThreadId);
TaskGestioneCartelle();
Application.Run(mainForm);
}
まず、アプリケーションを実行し、マウスを動かし続けます。Hang Loose
Label がマウスの追従を停止すると、UI スレッドがブロックされたことがわかります。
ここで、Output
デバッグから確認すると、次のようなものが表示されます。
UI Thread: 10
GeneraListaCartelle 6
GeneraListaCartelleCompletata 10
CopiaCartelle 10
CopiaCartelleCompletato 10
見る?UIスレッドを使用してタスクを実行しているため、UIがハングしています。
今、にTaskScheduler.FormCurrentSynchronizationContext()
変更TaskScheduler.Default
多田:
UI Thread: 8
GeneraListaCartelle 9
GeneraListaCartelleCompletata 10
CopiaCartelle 10
CopiaCartelleCompletato 11
ラベル テキストの変更など、mainForm.Invoke
で実行されるアクションを呼び出すために を使用していることに注意してください。UI Thread
さらに疑問がある場合は、お気軽にコメントしてください。