什么是Thread.Join()的替代方案来克服UI冻结问题

时间:2017-06-07 10:27:14

标签: c# multithreading parallel-processing

我有两个线程开始运行当用户选择播放按钮时。 但是当使用select Pause或Resume按钮时,我的UI因Thread.Join()而挂起。

下面是代码,我正在寻找一些替代方法来克服这个问题。 我已经尝试过使用Invoke,但即使使用这种方法它也无法工作,我的UI会在我调用Thread方法的时候冻结。

ThreadStart m_executeThreadStart;
        Thread m_executeThread;
        //user Selected Start Button
        private void Start()
        {
            m_executeThreadStart = new ThreadStart(method1);
            m_executeThread = new Thread(m_executeThreadStart);
            m_executeThread.Name = "ExecuteTestSession";
            m_executeThread.IsBackground = true;
            m_executeThread.Start();

            // Start the asynchronous operation.
            // InitializeBackgroundWorker();
            // backgroundWorker1.RunWorkerAsync();

            //Creating result sync thread
            ThreadStart m_resultSyncThreadStart = new ThreadStart(method2);
            Thread m_resultSyncThread = new Thread(m_resultSyncThreadStart);
            m_resultSyncThread.Name = "SyncResultDatabase";
            m_resultSyncThread.Start();
        }
        private void method1()
        {
            //do some work
            //read data from OPC sever (device)
        }
        private void method2()
        {
            //do some work
            //updated database accordingly method 1 data
        }

        //user Press Pause button
        public void Suspend()
        {
            //do work
            m_executeThread.Join();
            //do work
        }

        //user Press Resume button
        public void Resume()
        {
            //do work
            m_executeThread.Join();
            //do work
        }

2 个答案:

答案 0 :(得分:0)

我创建了解决方案,下面是回答的链接。

How to pause/suspend a thread then continue it?

ManualResetEvent mrse = new ManualResetEvent(true);    

 ThreadStart m_executeThreadStart;
        Thread m_executeThread;
        //user Selected Start Button
        private void Start()
        {
            m_executeThreadStart = new ThreadStart(method1);
            m_executeThread = new Thread(m_executeThreadStart);
            m_executeThread.Name = "ExecuteTestSession";
            m_executeThread.IsBackground = true;
            m_executeThread.Start();

            // Start the asynchronous operation.
            // InitializeBackgroundWorker();
            // backgroundWorker1.RunWorkerAsync();

            //Creating result sync thread
            ThreadStart m_resultSyncThreadStart = new ThreadStart(method2);
            Thread m_resultSyncThread = new Thread(m_resultSyncThreadStart);
            m_resultSyncThread.Name = "SyncResultDatabase";
            m_resultSyncThread.Start();
        }
        private void method1()
        {
            //do some work
            //read data from OPC sever (device)
              mrse.WaitOne();
        }
        private void method2()
        {
            //do some work
            //updated database accordingly method 1 data
              mrse.WaitOne();
        }

        //user Press Pause button
        public void Suspend()
        {
            //do work
            mrse.Reset();
            //do work
        }

        //user Press Resume button
        public void Resume()
        {
            //do work
             mrse.Set();
            //do work
        }

感谢您的帮助。

答案 1 :(得分:-1)

您可以向后台工作程序添加事件处理程序,然后您不需要Thread.Join()。然后,您的事件处理程序可以在长时间运行的进程完成时执行必要的操作:

backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
     // code to run after long running process has completed
}

异步/等待模式旨在阻止用户界面冻结(正确实施时)您可以将其用作替代方法 - https://docs.microsoft.com/en-us/dotnet/csharp/async

另见:https://docs.microsoft.com/en-us/windows/uwp/debug-test-perf/keep-the-ui-thread-responsive