c# - Task.Factory.StartNew 和主 UI

标签 c# winforms asynchronous

我正在学习 Task 的工作原理。我一直使用BackgroundWorker类或 Threading.Thread 类所以我想尝尝任务工厂。

在我正在构建的以下示例中,我恢复了

 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));
 }

最佳答案

您正在使用 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:

System.Threading.Tasks.TaskScheduler scheUI = System.Threading.Tasks.TaskScheduler.FromCurrentSynchronizationContext();
task.ContinueWith(p => PopulateList(task.Result),CancellationToken.None,
                              TaskContinuationOptions.ExecuteSynchronously |
                              TaskContinuationOptions.OnlyOnRanToCompletion,
                              scheUI);

关于c# - Task.Factory.StartNew 和主 UI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13630063/

相关文章:

c# - 在不重启服务器的情况下查看代码更改

c# - 在类定义中强制偏好重载?

python - 无法将.Net的SaveFileDialog与pythonnet一起使用

winforms - winforms 应用程序中托管的 MSIE WebBrowser 控件以兼容模式运行

c# - 车辆 GPS 跟踪设备

ios - Objective-C 中的同步和异步调用与多线程有什么区别?

c# - 找不到方法 : 'Boolean Microsoft. IdentityModel.Tokens.TokenUtilities.IsRecoverableConfiguration

c# - 为 UserControl 填充模型的正确方法是什么?

java - 同步执行存储过程

javascript - 数据库集群-异步任务