代码之家  ›  专栏  ›  技术社区  ›  VVS

“干点事就辞职”的最佳模式

  •  2
  • VVS  · 技术社区  · 15 年前

    我现在正在写一个小的GUI程序,做一些工作,然后退出。当工作完成时,GUI线程会为用户更新infos。

    static void MainForm_Loaded(BeoExport exporter)
    {
        // Thread 1 runs the Export
        workerThread = new Thread(() =>
        {
            exporter.StartExport();
            // don't exit immediately, so the user sees someting if the work is done fast
            Thread.Sleep(1000);     
        });
    
        // Thread 2 waits for Thread 1 and exits the program afterwards
        waiterThread = new Thread(() =>
        {
            workerThread.Join();
            Application.Exit();
        });
    
        workerThread.Start();
        waiterThread.Start();
    }
    

    那么你会用什么样的模式/机制来做同样的事情呢?

    澄清一下:我对更新GUI线程的方法不感兴趣。已经完成了。这可能听起来很深奥,但我正在寻找正确的方法退出应用程序。

    如果可以的话,我会给戴夫一个表扬,因为他指出了幕后工作者的用处。

    8 回复  |  直到 15 年前
        1
  •  2
  •   user203570 user203570    15 年前

    BackgroundWorker ReportProgress 方法和 ProgressChanged BeoExport.StartExport 方法也可以报告进度。这就为用户提供了工作实际发生的可视反馈。

        2
  •  2
  •   TcKs    15 年前

    ThreadPool.QueueUserWorkItem((state)=>{
        exporter.StartExport();
        Thread.Sleep(1000);
        Application.Exit();
    });
    
        3
  •  2
  •   Andrea Parodi    15 年前

    我建议你使用 BackgroundWorker 班级。它被认为是做你正在做的工作。你可以这样做:

    public class Form1 : Form
    {
        private BackgroundWorker worker;
        private ProgressBar bar;
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            bar= new ProgressBar();
            bar.Dock = DockStyle.Top;
            Controls.Add(bar);
    
            worker = new BackgroundWorker();
            worker.WorkerReportsProgress=true;
            worker.RunWorkerCompleted += delegate
                                             {
                                                 Close();
                                             };
            worker.ProgressChanged += delegate(object sender, ProgressChangedEventArgs ev)
                                          {
                                              bar.Value = ev.ProgressPercentage;
                                          };
            worker.DoWork += worker_DoWork;
            worker.RunWorkerAsync();
        }
    
        void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            //do your work here. For the example, just sleep a bit 
            //and report progress
            for (var i = 0; i < 100;i++ )
            {
                Thread.Sleep(50);
                worker.ReportProgress(i);
            }
        }
    
    }
    
        4
  •  1
  •   Francesco De Vittori    15 年前

    你可以使用 AutoResetEvent . 主线程等待autoreset事件被重置。

    var wh = new AutoResetEvent(false);
    
    var workerThread = new Thread(() =>
    {
        exporter.StartExport();
        // don't exit immediately, so the user sees something if the work is done fast
        Thread.Sleep(5000);
        wh.Set();
    });
    
    workerThread.Start();
    wh.WaitOne();
    
    Application.Current.Shutdown();
    
        5
  •  1
  •   Iain    15 年前

    Task Parallel Library 在.NET4中,您可以设置一个任务,而库将为您最好地并行化它,无论是线程,还是在单独的CPU内核上工作,都会在线提供大量有关它的信息。

        6
  •  1
  •   Conrad Frix    15 年前

    为了补充Lain的答案,这里有一个控制台示例,使用系统.Threading.Tasks命名空间。

     class Program
        {
            static void Main(string[] args)
            {
    
                Task<int> task  = Task<int>.Factory.StartNew(() =>
                    {
                        Exporter exporter = new Exporter();
                        int i = exporter.StartExport();
                        return i;
                     });
    
                int iResult = task.Result;
                Console.WriteLine(iResult);
                Console.ReadLine();
    
    
            }
    
            class Exporter {
                public int StartExport()
                {
                    //simulate some work
                    System.Threading.Thread.Sleep(500);
                    return 5;
                }
            }
        }
    
        7
  •  1
  •   Brian Gideon    15 年前

    使用 BackgroundWorker

    static void MainForm_Loaded(BeoExport exporter) 
    { 
        workerThread = new Thread(() => 
        { 
            exporter.StartExport(); 
            Thread.Sleep(1000);      
            MainForm.BeginInvoke(
              (Action)(() =>
              {
                MainForm.Close();
              });
        });
        workerThread.IsBackground = true;
        workerThread.Start();
    } 
    
        8
  •  0
  •   Anthony Williams    15 年前

    让工作线程向主线程发送一些描述的通知消息。然后,GUI可以根据需要退出或显示“done”消息。