如何异步这个长时间运行的方法?

时间:2015-09-16 20:04:50

标签: c# .net asynchronous async-await task-parallel-library

我有这个方法,我想异步运行,以便我可以在运行时做其他事情。它不依赖于任何其他Async方法(它不会调用另一个资源,下载文件或任何东西)。如果可能,我希望避免使用new Task()Task.Factory.StartTask()Task.Run()

是否可以异步运行此方法,使用整洁,可读的代码并且不显式使用任务?

如果没有,异步运行该方法的最简洁方法是什么?

注意:请不要担心方法中的愚蠢逻辑 - 我把它归结为故意慢但不显示我的实际代码。

public static void main(string[] args)
{
  RunMySlowLogic();
}

private void RunMySlowLogic()
{
  while (true)
    for (int i=0; i<100000000;i++)
      if (i == new Random().Next(999))
        return true;
}

目前,我认为我需要将该方法包装在lambda或Task中并将其标记为异步。等待去哪儿了?

2 个答案:

答案 0 :(得分:8)

你混淆了两件不同的事情。您可以在后台运行它,此方法可以是异步的。这些是两个不同的东西,你的方法可以做到或两者兼而有之。

如果您在该方法中执行异步操作,例如Task.Delay或某些非阻塞I / O,则调用该方法,等待返回的任务并使该方法本身为异步:

async Task RunMySlowLogicAsync()
{
    while (true)
    {
        // ...
        await Task.Delay(1000);
    }
}

如果你没有这样的东西,那么你的方法不是异步的,它是同步的。当您使用ThreadPool执行其他操作时,您仍然可以在后台使用其他(Task.Run)线程运行它:

var task = Task.Run(() => RunMySlowLogic());

答案 1 :(得分:0)

在.NET环境中有多种异步执行代码的方法。看看Asynchronous Programming Patterns MSDN article

任务是让您的工作更轻松。我认为避免使用任务的唯一正当理由是当你的目标是旧版本的.NET时。

因此,如果没有任务,您可以自己启动一个线程,或使用ThreadPool(任务在内部执行此操作)。

public static void main(string[] args)
{
  var are = new AutoResetEvent(false);
  ThreadPool.QueueUserWorkItem(RunMySlowLogicWrapped, are);
  // Do some other work here
  are.WaitOne();
}

// you have to match the signature of WaitCallback delegate, we can use it to communicate cross-thread
private void RunMySlowLogicWrapped(Object state) {
  AutoResetEvent are = (AutoResetEvent) state;
  RunMySlowLogic();
  are.Set();
}

private bool RunMySlowLogic() 
{
  while (true)
    for (int i=0; i<100000000;i++)
      if (i == new Random().Next(999))
        return true;
}