2

タスクの仕組みを学んでいます。BackgroundWorker クラスや Threading.Thread クラスをずっと使ってきたので、Task Factory を味わってみたくなりました。

私が構築している次の例では、

 Task<List<People>>

そして、タスクが終了したときに呼び出されると予想される「ContinueWith」を割り当てます。

以前のいくつかの例は素晴らしく機能していましたが、これは私のフリーズです

アプリ起動時のメインフォームUI。(私が行った他の例との違いはわかりません)。

メイン UI がフリーズする理由を知っていますか?

PS: 私は宣言することを知っています

System.Threading.Tasks.TaskScheduler scheUI

タスク宣言について。今は使っていませんが、後で使います。

前もって感謝します:

コードは次のとおりです。

 private void PopulateList(List<People> list)
            {
                if (listBox1.InvokeRequired)
                { 
                 listBox1.Invoke((MethodInvoker) delegate {

                     foreach (People item in list)
                    {
                        listBox1.Items.Add(item.name + " " + listBox1.Items.Add(item.surname));   
                    }

                 });
            }
        }



private Task<List<People>> GetPeopleListAsync(int PeopleNuber, int delaysecs)
        { 
         TaskScheduler scheUI = TaskScheduler.FromCurrentSynchronizationContext();
            return Task<List<People>>.Factory.StartNew( () =>
                {
                    List<People> listado = new List<People>();

                    for (int i = 0; i < PeopleNuber; i++)
                    {
                        People people = new People
                        {
                            name = "Name" + i.ToString(),
                            surname = "Surname " + i.ToString()
                        };

                        Thread.Sleep(delaysecs * 200);
                        listado.Add(people);
                    }

                    return listado;


                },CancellationToken.None,
                 TaskCreationOptions.None,scheUI);

        }


 void Form1_Load(object sender, EventArgs e)
 {


            Task<List<People>> task = GetPeopleListAsync(5, 10);
            task.ContinueWith(p => PopulateList(task.Result));
 }
4

1 に答える 1

4

次を使用して、最初のタスクを UI スレッドと同期しています。

System.Threading.Tasks.TaskScheduler scheUI = System.Threading.Tasks.TaskScheduler.FromCurrentSynchronizationContext();

最初のタスクから scheUI スケジューラを削除します。

return System.Threading.Tasks.Task<List<People>>.Factory.StartNew( () =>
            {
                List<People> listado = new List<People>();

                for (int i = 0; i < PeopleNuber; i++)
                {
                    People people = new People
                    {
                        name = "Name" + i.ToString(),
                        surname = "Surname " + i.ToString()
                    };

                    System.Threading.Thread.Sleep(delaysecs * 200);
                    listado.Add(people);
                }

                return listado;


            });

UI を更新するために実行される 2 番目のタスクに同期を追加する必要があります。

System.Threading.Tasks.TaskScheduler scheUI = System.Threading.Tasks.TaskScheduler.FromCurrentSynchronizationContext();
task.ContinueWith(p => PopulateList(task.Result),CancellationToken.None,
                              TaskContinuationOptions.ExecuteSynchronously |
                              TaskContinuationOptions.OnlyOnRanToCompletion,
                              scheUI);
于 2012-11-29T16:23:02.020 に答える