【问题标题】:Running a method with parameters in a thread in c#在c#中的线程中运行带参数的方法
【发布时间】:2022-02-17 17:08:22
【问题描述】:

我目前正在使用 C# 开发一个项目。我有一个名为 updateProgress() 的方法,它有两个 int 参数(count 和 totalRows)。

如果我通过说 updateProgress(count, totalRows) 来调用该方法,这可以正常工作,但我想在新线程中运行此方法。

我该怎么做呢,我在网上查了一下,对于我想做的事情来说,一切看起来都过于复杂。

感谢您对此的帮助

【问题讨论】:

  • 不要从工作线程更新 UI。

标签: c#


【解决方案1】:

类似这样的:

new Thread(delegate () {
    updateProgress(count, totalRows);
}).Start();

【讨论】:

  • 感谢大家的帮助
  • 试过Thread t = new Thread(new ParameterizedThreadStart(method)); t.Start(parameter);,但没用。不过,您的 sn-p 确实如此。谢谢
  • @Ortund method 有签名void method(object),还是其他类型的参数?
【解决方案2】:

请注意,线程实际上是一个相当复杂的主题,因此如果您在理解 .NET Framework 中可用的异步 API 时遇到困难,我怀疑您是否应该首先开始使用线程。

无论如何,你有几个选择:

  • 自己拆线(就像 cdhowie 指出的那样),这是相当不鼓励的。

  • 如果您在 .NET 4 上运行,请使用 TPL(任务并行库)。Here 是一个很好的介绍。 TaskFactory.StartNew(() => updateProgress(count, totalRows));

  • 如果您在旧版本的 .NET 上运行,请使用 ThreadPool。 ThreadPool.QueueUserWorkItem(s => updateProgress(count, totalRows));

当然还有其他方法,但这是 imo 最重要的方法。

最好的问候,
奥利弗·哈纳皮

【讨论】:

    【解决方案3】:

    这已经快一年了,我的回答不会对其他答案中已经说过的内容添加任何“新”

    如果有人使用 .Net 4.0 或更高版本,最好的选择是使用任务并让框架决定最好的,方法是调用 TaskFactory.StartNew(...)。对于旧版本,最好还是使用ThreadPool.QueueUserWorkItem(...)来利用线程池。

    现在,如果仍然有人出于某种原因想要以基本方式(创建新线程)使用线程,那么这个

    new Thread(delegate () {
        updateProgress(count, totalRows);
    }).Start();
    

    可以用更简洁的方式编写,使用 lambda 表达式,像这样

    new Thread(() => updateProgress(count, totalRows)).Start();
    

    【讨论】:

      【解决方案4】:

      在不同的线程中运行方法有不同的方法,例如ThreadBackgroundWorkerThreadPoolTask。选择哪一个取决于各种因素。

      从方法的名称来看,听起来该方法应该在应用程序的 GUI 中显示一些进度。如果是这种情况,您必须在 GUI 线程上运行该方法。如果你想从另一个线程调用它,你必须在WPF中使用Dispatcher.Invoke(),在WinForms中使用Control.Invoke()

      【讨论】:

        【解决方案5】:

        尝试关注

        ThreadPool.QueueUserWorkItem((o) => { updateProgress(5, 6); });
        

        【讨论】:

          【解决方案6】:

          这是一个没有匿名委托的更复杂的示例。在完成的函数中查看结果。

          using System;
          using System.Threading;
          using System.ComponentModel;
          
          class Program
          {
            static BackgroundWorker _bw;
          
            static void Main()
            {
              _bw = new BackgroundWorker
              {
                WorkerReportsProgress = true,
                WorkerSupportsCancellation = true
              };
              _bw.DoWork += bw_DoWork;
              _bw.ProgressChanged += bw_ProgressChanged;
              _bw.RunWorkerCompleted += bw_RunWorkerCompleted;
          
              _bw.RunWorkerAsync ("Hello to worker");
          
              Console.WriteLine ("Press Enter in the next 5 seconds to cancel");
              Console.ReadLine();
              if (_bw.IsBusy) _bw.CancelAsync();
              Console.ReadLine();
            }
          
            static void bw_DoWork (object sender, DoWorkEventArgs e)
            {
              for (int i = 0; i <= 100; i += 20)
              {
                if (_bw.CancellationPending) { e.Cancel = true; return; }
                _bw.ReportProgress (i);
                Thread.Sleep (1000);      // Just for the demo... don't go sleeping
              }                           // for real in pooled threads!
          
              e.Result = 123;    // This gets passed to RunWorkerCompleted
            }
          
            static void bw_RunWorkerCompleted (object sender,
                                               RunWorkerCompletedEventArgs e)
            {
              if (e.Cancelled)
                Console.WriteLine ("You canceled!");
              else if (e.Error != null)
                Console.WriteLine ("Worker exception: " + e.Error.ToString());
              else
                Console.WriteLine ("Complete: " + e.Result);      // from DoWork
            }
          
            static void bw_ProgressChanged (object sender,
                                            ProgressChangedEventArgs e)
            {
              Console.WriteLine ("Reached " + e.ProgressPercentage + "%");
            }
          }
          

          【讨论】:

          • “……没有代表”是什么意思?我在您的代码中看到了几个隐式方法组转换。
          • 它使用函数而不是内联委托。有时它们更易于使用和阅读,特别是对于新线程用户而言。
          • 那么我认为你应该澄清一下“没有匿名代表”。否则,OP 可能会完全忽略 ProgressChangedEventHandler 委托实例正在创建的事实。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-12-27
          • 1970-01-01
          • 2011-01-18
          • 1970-01-01
          • 2015-01-24
          • 1970-01-01
          相关资源
          最近更新 更多