【问题标题】:c# which is the best way for doing a larger task without interrupting whole programc# 这是在不中断整个程序的情况下完成更大任务的最佳方式
【发布时间】:2017-12-22 04:43:03
【问题描述】:

我的问题是我想执行一些操作,例如从某个 URL 获取数据(格式为字符串)。我想运行这个过程是后台。每当用户需要此操作时,我都必须调用此操作。就像用户单击为此操作指定的按钮一样,它应该执行该功能并向该用户提供结果。问题是当执行此程序时,不应中断其他程序。我想运行这种异步方式。我想返回从 URL 下载的结果 这是我使用线程的解决方案

namespace xyz
{

    public class newWinForm : Form
    {
        SomeClass someClass = new SomeClass();

        public newWinForm()
        {
          Thread backgroundThread = new Thread(DoWork);
          backgroundThread.IsBackground = true;
          backgroundThread.Start();

         }
         void DoWork()
         {
            try
            {
              Console.WriteLine("Doing some work...");
              using(WebClient cl = new WebClient())
              {
               string result = cl.DownloadString("http://www.......com");
              } 
              Thread.Sleep(1000);
             }
             finally
             {
               Console.WriteLine("This should be always executed");
             }
          }
         private void getDataFrmUrlButton_Click(object sender, EventArgs e)
         {
          Thread backgroundThread = new Thread(DoWork);
          backgroundThread.IsBackground = true;
          backgroundThread.Start();
         }
}

【问题讨论】:

    标签: c# multithreading background-task background-thread


    【解决方案1】:

    您可以使用 backgroundworker 类来完成您的任务

    private BackgroundWorker bg1 = new BackgroundWorker();
     bg1.DoWork += bg1_DoWork;
    
     private void bg1_DoWork(object sender, DoWorkEventArgs e)
            {
               //the function you want to execute
            }
    

    【讨论】:

    • 嗯,看起来和Thread.Isbackground = true; 一样,我想要的结果就像我调用string x = getStringResult(); 一样,如果getResult 包含返回字符串类型的代码,我将在x 中得到结果。在这个后台工作人员执行后,我如何返回并为某个字符串赋值?喜欢string result = backgroudnworker?Result();
    • 在类中(方法外)声明字符串,然后就可以通过backgroundWorker中的函数操作该字符串
    • 有一个 RunWorkerCompleted 事件:MSDN
    【解决方案2】:

    在这种情况下,您的操作受 I/O 限制,因此最好采用异步方法。为此,您可以在事件中使用 async 关键字。

    private async void getDataFrmUrlButton_Click(object sender, EventArgs args)
    {
        using(var client = new WebClient())
        {
            string result = await client.DownloadStringTaskAsync(uri);
    
            // Do stuff with data
        }
    }
    

    This post 提供了一些很好的资源,以获取有关async/await 的更多信息。

    【讨论】:

    • 正确,无需显式创建新线程。通过使用async/await,您的主线程将在应用程序等待响应时重新获得控制权。当数据准备好并继续运行您的方法时,它会在后台发送一个事件。
    • 好的!但是异步方法总是无效的!是否可以返回字符串?
    • 您可以通过返回Taskasync 方法返回数据。所以如果你想返回一个字符串,它看起来像这样:private async Task<string>。但在这种情况下,我们在一个事件中有async,所以我们必须返回void。所以你需要做类似@hustlecoder 建议的事情,在你的类中使用一个成员变量。
    【解决方案3】:

    如果您想要更多基于企业的解决方案,可以查看 Hangfire (https://www.hangfire.io/)。

    虽然通常针对 ASP.NET 解决方案,但您也可以将其作为 windows service 的一部分运行,并将其与基于 WinForm 的应用程序结合使用。即使您不想使用TPL 自己做,它也可以让您轻松移交长时间运行的任务并跟踪它们。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-02-26
      • 1970-01-01
      • 1970-01-01
      • 2019-08-15
      • 2021-07-31
      • 1970-01-01
      • 2013-01-29
      相关资源
      最近更新 更多