2015-03-03 69 views
0

我有两种方法。我想等待第一个,有时候等待另一个(但不是所有的时间)。所以我想我应该使用一项任务,等待它,等待,而不是等待。将同步方法转换为与C#异步#

编辑:事实上,我只需要一个火,忘记呼叫? :

public class TestController : ApiController 
{ 
    public IHttpActionResult Get(int id) 
    { 
     Stopwatch sw = Stopwatch.StartNew(); 

     JobRunner runner = new JobRunner(); 
     bool iWantToWait = id == 1; 

     string jobId = runner.Run(!iWantToWait); 
     sw.Stop(); 
     return Ok("Ok " + jobId + " # " + sw.Elapsed); 
    } 
} 

public class JobRunner 
{ 
    public string Run(bool fireAndForget) 
    { 
     ShortMethodIAlwaysWantToWait(); 
     string jobId = Guid.NewGuid().ToString("N"); 
     if (fireAndForget) 
      HostingEnvironment.QueueBackgroundWorkItem(token => LongMethodICouldWantToWaitOrNot(jobId)); 
     else 
      LongMethodICouldWantToWaitOrNot(jobId); 
     return jobId; 
    } 

    private void ShortMethodIAlwaysWantToWait() 
    { 
     // ... 
    } 

    private void LongMethodICouldWantToWaitOrNot(string jobId) 
    { 
     // ... 
    } 
} 

回答

2
public class JobRunner 
{ 
    public async Task<string> Run(bool fireAndForget) 
    { 
     await ShortMethodIAlwaysWantToWait(); 
     string jobId = Guid.NewGuid().ToString("N"); 
     if (fireAndForget) 
      HostingEnvironment.QueueBackgroundWorkItem((token) => LongMethodICouldWantToWaitOrNot(jobId)); 
     else 
      await LongMethodICouldWantToWaitOrNot(jobId); 
     return jobId; 
    } 

    private async Task LongMethodICouldWantToWaitOrNot(string jobId) 
    { 
     await Task.Delay(5000); 
    } 

    private async Task ShortMethodIAlwaysWantToWait() 
    { 
     await Task.Delay(2000); 
    } 
} 

照顾后台任务在ASPNET,净4.5.2之前,你不应该“射后不理”异步方法,因为线程可以的结束前被中止任务。由于4.5.2可以使用HostingEnvironment.QueueBackgroundWorkItem

+0

虽然请注意,由于LongMethod现在在同一个线程上运行,因此您不会等待'ShortMethodIAlwaysWantToWait' – 2015-03-03 10:11:38

+0

。虽然可以很容易地用'await Task.Run()'在另一个线程上运行。 – GazTheDestroyer 2015-03-03 10:11:43

+0

感谢您的回答。 Thread.Sleep当然是一个例子,我正在访问一些资源。我是否需要异步LongMethodICouldWantToWaitOrNot?或者它只能是一个空白? – Tim 2015-03-03 10:13:07

0
 public async Task<string> Run() 
     { 
      ShortMethodIAlwaysWantToWait(); 
      string jobId = Guid.NewGuid().ToString("N"); 

      if (iwantToAWait) { 
       var task = Task.Run(() => LongMethodICouldWantToWaitOrNot(jobId)); 
       await task; 
      } 
      else 
       LongMethodICouldWantToWaitOrNot(jobId) 

      return jobId; 
     } 

这样,Task要么等待:在控制返回给调用者,那么谁可以决定是否要等待或等待,或Task是等待而阻断当前线程。

你可能想要么改变你的动作要async和更新的呼叫:

string jobId = await runner.Run(); 

,也可以使用Task<string>

var task = runner.Run(); 
task.Wait(); 
string jobId = task.Result; 

编辑做同样的:重要的是是否LongMethodICouldWantToWaitOrNot正在执行CPU绑定操作,在这种情况下,使用Task.Run运行它是有意义的,或者该方法的“缓慢”是否由I/O操作引起,在这种情况下,您应该使其成为async,我看不到任何同步运行的原因

+0

'异步'方法中的'Wait'?什么是在线程池线程中执行并同步等待?为什么不调用'LongMethodICouldWantToWaitOrNot'? – 2015-03-03 10:16:33

+0

这就是OP要求的。我不是挑战问题的支持者。他想等待或等待,取决于某些内容......在线程池中执行确实是不必要的。更新答案。 – Steves 2015-03-03 10:20:58

+0

我有时会等待,有时候不会。我看不到OP要求什么时候同步等待。真的问题至少对我来说还不清楚。但是,如果你想在'async'方法中同步等待,那么你正在做一些非常错误的事情。 – 2015-03-03 10:25:40