【问题标题】:Stop execution of a method c#停止执行方法c#
【发布时间】:2014-08-06 09:36:52
【问题描述】:

当我点击一个按钮时,我怎样才能停止我的方法的执行?

  public void ForEach()
    {
        CreateFolders();

        //For each process get the equivalent processcode
        foreach (string item in Processes)
        {
            ItemValue = item;
            //Get process code for the process under the selected source
            GetActiveProcess();

            #region Switch
            switch (ProcessCode)
            {
                #region DownloadFile
                case "Download File":
                    ForDownloadFile();
                    break;
                #endregion

                #region UnzipFile
                case "Unzip File":
                    ForUnzipFile();

                    break;
                #endregion

                #region RenameFile
                case "Rename File":
                    ForRenameFile();
                    break;
                #endregion

                #region MergeFile
                case "Merge File":
                    ForMergeFile();
                    break;
                #endregion

                #region ZipFile
                case "Zip File":
                    ForZipFile();
                    break;
                #endregion

                #region UploadFile
                case "Upload File":
                    ForUploadFile();
                    break;
                #endregion
            }
            #endregion

        }


    }

当我单击停止按钮时,如何结束我的 public void foreach。当我点击停止而不关闭我的应用程序时,我想停止下载或提取文件等。

我已尝试使用 return,但它会继续执行(下载/提取等)。

【问题讨论】:

  • 您自己尝试过吗?
  • @Dan Puzey,我尝试使用 return 但它继续执行。它继续下载,或提取等
  • 您是否在后台线程中运行代码?
  • 使用 BackgroundWorker
  • @DanPuzey,我已经通过分配一个布尔取消来解决它,一旦它变为真,它就会返回。我把它放在我所有的方法中(ForZipFile、ForMergeFile 等)

标签: c# wpf methods


【解决方案1】:

你不能停止单个方法的执行。您可以通过使用线程来使用它。 使用新线程运行该方法,并在按钮单击时发出信号停止线程。 看看这个线程 - C# Threading - How to start and stop a thread http://msdn.microsoft.com/en-us/library/7a2f3ay4(v=vs.90).aspx

【讨论】:

    【解决方案2】:

    快速而肮脏的解决方案可能是引入一个变量测试,并通过按下停止按钮来设置这个变量。请注意,这仅适用于 WinForm 应用程序,对于 WPF 应用程序,您需要导入 system.windows.forms.dll - 有效地使其成为非 wpf。

    例如:

    bool stop = false;
    
    foreach (string item in Processes)
    {
        if (stop)
            break;
    
        //do-your-stuff
    
        Application.DoEvents(); //this will force the winform app to handle events from the GUI
    }
    
    //Add an eventhandler to your stop-button
    private void stopButton_Click(System.Object sender, System.EventArgs e)
    {
        stop = true;
    }
    

    但是,正如 Rabi 所建议的,在您的应用程序中引入一些线程会更好。对于 WPF,Dispatcher 会创造奇迹。请参阅http://msdn.microsoft.com/en-us/magazine/cc163328.aspx

    【讨论】:

    • 感谢您的想法。我已经通过使用布尔取消解决了我的问题,其中当它变为真时它将返回。我用过 if(cancel == true) return;在我的 foreach() 方法中的每个方法中。当我单击停止按钮时,它将使我的取消为真。谢谢。
    • 只需使用 if (cancelled) 。 if (cancel == true) 看起来像糟糕的编码练习:)
    【解决方案3】:

    停止您的 ForEach() 应该很容易,但停止您为每个案例定义的每个方法取决于您在这种情况下所做的事情。

    // Defined somewhere which is available to you ForEach() and your Stop button.
    // In the stop button set the KeepProcessing to false.
    bool KeepProcessing = true;   
    
    foreach (string item in Processes)
    {
        if(!KeepProcessing)
             return;
    
        switch(.....
    }
    

    【讨论】:

      【解决方案4】:

      取消工作线程执行的最规范技术是一种称为合作取消的模式。 MSDN has a nice article on it。请注意,这与使用基于任务的异步编程有关。

      大意是这样的:

      public void DoWork(IEnumerable<Work> workItems, ref bool cancel)
      {
          foreach(thing in workItems)
          {
              //poll to see if you need to abandon the work.
              if(cancel)
                  throw new WorkCancelledException(); //or whatever exception you want to use. MSDN shows you a built in one.
      
              ProcessThing(thing); //process the item. An item is just a unit of work. You dont have to use a collection of work items.
          }
      }
      

      按下取消按钮时,设置取消布尔值。 MSDN 示例使用CancellationToken,我会推荐它。它不限于Task 实现。

      为什么要合作?在cancel为真时,消费代码和执行代码都必须同意取消的方法,并同意取消操作。

      【讨论】:

        【解决方案5】:

        我不习惯 Wpf,但如果你需要使用线程,我认为使用 BackGroundWorker 是一个正确的解决方案。

        https://stackoverflow.com/a/5483644/906404

        private readonly BackgroundWorker worker = new BackgroundWorker();
        
        // Initialization code
        worker.DoWork += worker_DoWork;
        worker.WorkerSupportsCancellation = true;
        worker.RunWorkerAsync();          // Runs your code in a background thread
        
        private void worker_DoWork(object sender, DoWorkEventArgs e)  
        {
            CreateFolders();
        
            //For each process get the equivalent processcode
            foreach (string item in Processes)
            {
        
           -->> if (worker.CancellationPending) break;
        
                ItemValue = item;
                //Get process code for the process under the selected source
                GetActiveProcess();
        
        
                ... your code... 
        
            }
        }
        
        void OnClickStopButton(args) {
           worker.CancelAsync();
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-04-03
          • 1970-01-01
          • 2016-07-14
          • 2021-03-02
          • 2017-06-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多