运行任务时 UI 被冻结

发布于 2024-12-22 23:40:46 字数 2508 浏览 6 评论 0原文

可能我错了,但我的假设是,如果我不关心任何特定顺序,任何后台线程都可以读取和写入 List 或 ObservableCollection 。如果我需要保留订单,我将使用 BlockingCollection。

    private void buttonTesting_Click(object sender, RoutedEventArgs e)
    {
        PrepareDataForTesting();                
        Stopwatch timer1 = new Stopwatch();
        timer1.Start();           

        //some code preparing data

        List<Task> tasks = new List<Task>();

            //Testing for each pair 
        foreach (InterfaceWithClassName aCompound in Group1) 
        { 
            foreach (InterfaceWithClassName bCompound in Group2) 
            { 
                InstancePair pair = new InstancePair(); 
                //some code 

                Task task = Task.Factory.StartNew(() => TestPairSerial(pair));
                 tasks.Add(task);
             }
          }                

            var ui = TaskScheduler.FromCurrentSynchronizationContext();

            Task.Factory.ContinueWhenAll(tasks.ToArray(),
                antecedents =>
                {
                    timer1.Stop();
                    TimeSpan ts1 = timer1.Elapsed;
                    string elapsedTime1 = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts1.Hours, ts1.Minutes, ts1.Seconds, ts1.Milliseconds / 10);
                    statusLabel_1.Content = "Elapsed time to run the test" + elapsedTime1;
                    statusLabel_0.Content = "Testing made " + passes + " passes";
                    pairsResultsDataGrid.ItemsSource = pairsResultsTable.DefaultView;
                    System.Media.SystemSounds.Exclamation.Play();

                }, CancellationToken.None, TaskContinuationOptions.None, ui);            

                System.Media.SystemSounds.Beep.Play();               
            }

(注意:我不确定这是否重要 - “对”是通过反射找到的) 当我单击按钮时,我可以听到最后一行 - System.Media.SystemSounds.Beep.Play();这意味着我们退出了事件处理程序并且所有线程都启动了。但是我的应用程序仍然被冻结,直到ContinueWhenAll 完成。 TestPairSerial(pair) 方法具有以下结构:

private void TestPairSerial(object instances)
    {
      do 
      { 
          do 
           { 
             //here are two methods that read data from minData ObservableCollection
             //minData is a public static property of MainWindow
             //minData is bound to Chart control (in XAML)

            } while (isSetbCompoundParams); 

        } while (isSetaCompoundParams); 

              //filling up results into one table and two dictionaries (main window variables)
    }

May be I am wrong but my assuption is that any background thread can read and write into List or ObservableCollection if I don't care about any particular order. If I need a surtain order I will use BlockingCollection.

    private void buttonTesting_Click(object sender, RoutedEventArgs e)
    {
        PrepareDataForTesting();                
        Stopwatch timer1 = new Stopwatch();
        timer1.Start();           

        //some code preparing data

        List<Task> tasks = new List<Task>();

            //Testing for each pair 
        foreach (InterfaceWithClassName aCompound in Group1) 
        { 
            foreach (InterfaceWithClassName bCompound in Group2) 
            { 
                InstancePair pair = new InstancePair(); 
                //some code 

                Task task = Task.Factory.StartNew(() => TestPairSerial(pair));
                 tasks.Add(task);
             }
          }                

            var ui = TaskScheduler.FromCurrentSynchronizationContext();

            Task.Factory.ContinueWhenAll(tasks.ToArray(),
                antecedents =>
                {
                    timer1.Stop();
                    TimeSpan ts1 = timer1.Elapsed;
                    string elapsedTime1 = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts1.Hours, ts1.Minutes, ts1.Seconds, ts1.Milliseconds / 10);
                    statusLabel_1.Content = "Elapsed time to run the test" + elapsedTime1;
                    statusLabel_0.Content = "Testing made " + passes + " passes";
                    pairsResultsDataGrid.ItemsSource = pairsResultsTable.DefaultView;
                    System.Media.SystemSounds.Exclamation.Play();

                }, CancellationToken.None, TaskContinuationOptions.None, ui);            

                System.Media.SystemSounds.Beep.Play();               
            }

(Note: I am not sure if it matters - "pair" is found through Reflection)
When I click the button I can hear the last line - System.Media.SystemSounds.Beep.Play(); meaning we out of the event handler and all the threads are launched. But then my application is still frozen untill ContinueWhenAll is done.
TestPairSerial(pair) method has the following structure:

private void TestPairSerial(object instances)
    {
      do 
      { 
          do 
           { 
             //here are two methods that read data from minData ObservableCollection
             //minData is a public static property of MainWindow
             //minData is bound to Chart control (in XAML)

            } while (isSetbCompoundParams); 

        } while (isSetaCompoundParams); 

              //filling up results into one table and two dictionaries (main window variables)
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一腔孤↑勇 2024-12-29 23:40:46

您正在主线程中执行任务。您可以使用 Dispatcher.BeginInvoke 异步执行整个代码

this.Dispatcher.BeginInvoke(new Action(() => {
    // your code here
}), null);

You are executing the tasks in the main thread. You can execute the whole code asynchronously with Dispatcher.BeginInvoke

this.Dispatcher.BeginInvoke(new Action(() => {
    // your code here
}), null);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文