调用的方法,并继续在C#

问题描述:

如果我有以下几点:调用的方法,并继续在C#

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

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

我怎样才能改变DoSomethingQuick(),使其返回“进程启动”的瞬间,而不是等待DoSomethingThatTakes10Minutes()完成第一?

+2

请参阅[这个答案](http://stackoverflow.com/questions/14455293/async-and-await#answer-19985988)和等待。 – 2014-10-28 23:41:31

+0

我可以问你如何在你的搜索中找不到什么异步的东西? – Default 2014-10-28 23:47:07

+0

Downvoting,因为这个问题没有显示研究工作。如果您已经完成了研究,但有些事情不清楚,请将其添加到您的问题中。 – Default 2014-10-28 23:48:07

旁边的事实,是这应该是很快包含的东西,应该需要很长的时间...... 您可以使用一个线程来做到这一点

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

+1

这是一个非常糟糕的解决方案。 't'作用域是本地的,但是线程本身是应用程序全局的。您还没有将线程标记为背景,因此如果用户关闭了应用程序UI,则无论线程完成,流程本身都会处于停滞状态,此时您不知道会发生什么情况。 – Polynomial 2014-10-28 23:37:27

+0

修正了这个问题,我只想给你一个关于如何使用线程的简单例子,但是你对此是正确的。 – 2014-10-28 23:40:39

一个你能解决这个问题的方法是使用异步和等待,就像这样:

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"; 
} 

正如您在输出窗口中看到的,在AsyncExample()完成并写入一行之前,将执行Console.WriteLine(“首先打印”)。

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

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

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

    backgroundWorker.RunWorkerAsync(); 

    return "Process Started"; 
} 

需要注意的是,在很多情况下,单独的线程将无法改变非静态从主线程创建的对象,所以你要么需要使用调度员或包含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 
};