【问题标题】:what is wrong with my code.. my gui hangs我的代码有什么问题..我的 gui 挂起
【发布时间】:2016-01-30 23:35:42
【问题描述】:

我运行这个算法,当我在我的 GUI 上按下 Stop 时,它挂起,然后我在 VS 上按下暂停,只是为了查看我的代码光标在哪里,它指向或或多或少地击中 thread.join()。并且内部异常是线程正在等待或睡眠..这发生了大约 30 秒,GUI 稍后可以正常工作..

如何使 gui 不挂起,而是让代码线程运行,并且一旦完成更改应反映在 GUI 上

namespace ILS.PLMOptimization
{
    public class PLMOptimizationLoop : Disposable
    {
        private Thread PLMOptimizerThread;

        private AutoResetEvent stopEvent;

        public IOptimizer Optimizer { get; private set; }

        private static PLMOptimizationLoop instance;

        //Singleton Pattern Used
        public static PLMOptimizationLoop Instance
        {
            get { return (instance ?? (instance = new PLMOptimizationLoop())); }
        }
        protected override void Dispose(bool disposing)
        {
            SafeDispose(ref stopEvent);

            base.Dispose(disposing);
        }

        private void OptimizationThread()
        {
            if (Optimizer == null)
                throw new NullReferenceException("Optimizer");

            Optimizer.Initialize();

            while (true)
            {
                // if stopped externally
                if (this.stopEvent.WaitOne(1000))
                break;

                // execute optimizer, continue to call execute only if the optimizer requires it
                if (this.Optimizer.Execute())
                    continue;

                // set thread to null only if exiting on its own
                // in case stop was called the caller will wait for this thread to exit
                // and then make the thread object null
                this.PLMOptimizerThread = null;
                break;
            }

            Optimizer.Shutdown();
        }

        private PLMOptimizationLoop()
        {
            this.stopEvent = new AutoResetEvent(false);
            this.PLMOptimizerThread = null;
        }

        int a = 0;
        public void Start(IOptimizer optimizer)
        {
            a = 1;
            if (optimizer == null)
                throw new ArgumentNullException("optimizer");

            this.Optimizer = optimizer;

            this.PLMOptimizerThread = new Thread(OptimizationThread);
            this.PLMOptimizerThread.Start();
        }

        public void Stop()
        {
            if (this.PLMOptimizerThread == null)
                return;

            this.stopEvent.Set();

            this.PLMOptimizerThread.Join();// **********the problem seems to be here ****//
            this.PLMOptimizerThread = null;
        }
    }
}

这是我上面代码试图运行的算法:

namespace ILS.PLMOptimization.Algorithm
{
    public class PLMOptimizationAlgorithm : IOptimizer
    {
        public void Initialize()
        { 
            //somecode here
        } 

        public bool Execute()
        {
            //somecode here
        }

        public void Shutdown()
        {
            //somecode here
        }

        public int ResetLuminaire_To_DefaultStateonSTop()
        {
            //somecode here
        }

        public PLMOptimizationAlgorithm()
        {
            //somecode here
        }
    }
}

【问题讨论】:

  • Thread.Join 的意思是“嘿,当前线程,请等待其他线程完成”。在您的情况下,当前线程是调度程序线程,因此 UI 挂起。
  • 感谢您的回复先生,我可以改进的代码样式的修改是什么
  • 在线程中执行 Stop() 函数

标签: wpf multithreading


【解决方案1】:

如果“Execute”方法耗时较长,线程将不会接收到停止事件,GUI线程会阻塞在join-Method中。如果您通过 stopEvent 发出取消请求,则必须更频繁地评估此事件,这也意味着在长时间运行的 Execute-Method 中。 CancellationToken (https://msdn.microsoft.com/de-de/library/dd997364%28v=vs.110%29.aspx) 有时对这个目的更有用,你必须将它传递给每个长时间运行的函数,在这种情况下是 Execute。许多内置功能支持通过此令牌取消。

如果您想在 Optimizer 线程中更新 WPF-GUI,请使用 Dispatcher 将请求传递给 GUI-Thread:Using the C# Dispatcher

【讨论】:

  • 谢谢你,先生。我可以在链接上..你能告诉我我可以在我的代码中实现它以提高效率
猜你喜欢
  • 1970-01-01
  • 2011-07-28
  • 1970-01-01
  • 1970-01-01
  • 2019-06-06
相关资源
最近更新 更多