【问题标题】:Calling a method and continuing in c#调用方法并在 C# 中继续
【发布时间】:2014-10-28 23:34:35
【问题描述】:

如果我有以下情况:

public string DoSomethingQuick()
{
  DoSomethingThatTakes10Minutes();
  return "Process Started"; 
}

public void DoSomethingThatTakes10Minutes()
{
/// code to do something that takes 10 minutes
}

如何更改 DoSomethingQuick() 使其立即返回“进程已启动”,而不是等待 DoSomethingThatTakes10Minutes() 先完成?

【问题讨论】:

  • 使用 async 和 await 查看 this answer
  • 请问您是如何在搜索中没有发现有关启动异步内容的?
  • 投反对票,因为这个问题没有显示任何研究工作。如果您已经进行了研究但有不清楚的地方,请将其添加到您的问题中。
  • 这是在任何情况下,例如Windows 应用程序还是网站?

标签: c# asynchronous methods


【解决方案1】:

解决此问题的一种方法是使用 async 和 await,如下所示:

public void Main()
{
    AsyncExample();

    Console.WriteLine("prints first");
}

public async Task AsyncExample()
{
    Task<string> executesSeparately = ExecutesSeparately();

    string result = await longRunningTask;

    Console.WriteLine(result);
}

public async Task<string> ExecutesSeparately()
{
    await Task.Delay(2000);
    return "prints second";
}

您将在输出窗口中看到,Console.WriteLine("prints first") 在 AsyncExample() 完成并写入一行之前执行。

解决此问题的另一种方法是使用 BackgroundWorker。

public string DoSomethingQuick()
{
    var backgroundWorker = new BackgroundWorker();

    backgroundWorker.DoWork += delegate(object s, DoWorkEventArgs args)
    {
         DoSomethingThatTakes10Minutes();
    };

    backgroundWorker.RunWorkerAsync();

    return "Process Started"; 
}

请注意,在很多情况下,单独的线程将无法更改从主线程创建的非静态对象,因此您需要使用 Dispatcher 或在调用中包含 UI 线程逻辑到 BackgroundWorker.ReportProgress(),它会自动在 UI 线程上工作。看起来更像这样:

 var backgroundWorker = new BackgroundWorker() { WorkerSupportsCancellation = true };

 backgroundWorker.ReportProgress += delegate(object s, ProgressChangedEventArgs e)
 {
     DoSomethingThatTakes10MinutesAndExecutedOnUiThread();
 }

 backgroundWorker.DoWork += delegate(object s, DoWorkEventArgs e)
 {
     backgroundWorker.ReportProgress(0); // the progress value is irrelevant
 };

【讨论】:

    【解决方案2】:

    除了对于一个应该快速包含应该需要很长时间的东西的方法来说非常模棱两可的事实...... 您可以使用线程来完成它

        Thread t;
    
        public string DoSomethingQuick()
        {
          t=new Thread(DoSomethingThatTakes10Minutes);
          t.isBackground=true;
          t.Start();
          return "Process Started"; 
        }
    

    有关线程的更多信息:http://msdn.microsoft.com/it-it/library/system.threading.thread(v=vs.110).aspx

    【讨论】:

    • 这是一个非常糟糕的解决方案。 t 是局部作用域,但线程本身是应用程序全局的。您还没有将线程标记为背景,因此如果用户关闭应用程序 UI,进程本身将一直挂起,直到线程完成,此时您不知道会发生什么。
    • 解决了这个问题,我只想给你一个关于如何使用线程的简单示例,但你说得对。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-11
    • 2020-02-18
    • 1970-01-01
    • 2013-03-13
    • 1970-01-01
    • 2019-03-12
    相关资源
    最近更新 更多