C#启动任务运行异步方法

问题描述:

我试图创建将运行异步方法的任务,问题是,我不能awaitAction参数在任务的构造函数,或Task.Factory.StartNew的参数。C#启动任务运行异步方法

根据我如何实例化我的任务,我有不同的问题。我已经提供了七个例子,并对各自在下面创建的问题发表了评论

示例代码:(任务创建的7个例子)

private ConcurrentDictionary<int, Task> Tasks { get; set; } 
    private bool active = true; 

    private async Task StartTasks() 
    { 
     int numTasks = 5; 

     for(int i = 0; i < numTasks; i++) 
     { 
      //Task status is almost instantly "RanTocompletion" while work is still being done 
      Task task = new Task<Task>(DoWork, "someinfo", TaskCreationOptions.LongRunning); 
      task.Start(); 

      //Cannot await method group 
      Task task = new Task(await DoWork, "someinfo", TaskCreationOptions.LongRunning); 
      task.Start(); 

      //Task status is almost instantly "RanTocompletion" while work is still being done 
      Task task = new Task(async (object state) => await DoWork(state), "someinfo", TaskCreationOptions.LongRunning); 
      task.Start(); 

      //Throws a "Start may not be called on a promise-style task." Exception 
      Task task = new Task<Task>(DoWork, "someinfo", TaskCreationOptions.LongRunning).Unwrap(); 
      task.Start(); 

      //Task starts doing work after Start() is called, then throws a "Start may not be called on a promise-style task." Exception 
      Task task = new Task(DoWork, "someinfo", TaskCreationOptions.LongRunning); 
      task.Start(); 

      //Task starts doing work, but status is "WaitingForActivation 
      Task task = Task.Factory.StartNew(DoWork, "someinfo", TaskCreationOptions.LongRunning); 

      //Throws a "Start may not be called on a promise-style task." Exception 
      Task task = Task.Factory.StartNew(DoWork, "someinfo", TaskCreationOptions.LongRunning).Unwrap(); 

      //For checking up on tasks as work is done 
      Tasks.TryAdd(task.Id, Task); 
     } 
    } 

    private async Task DoWork(object state) 
    { 
     while (active) 
     { 
      await MakeHttpRequest(); 
      await DoSomethingCpuBound(); 
      //..etc 
     } 
     //do any cleanup and return 
    } 

我不能使用Task.Run(),因为不提供TaskCreationOptions。这些任务将在字面上运行。

如何启动任务以等待异步操作?

+5

这听起来像是一个X-Y问题。你试图解决X,你认为Y是答案,但是你不知道如何去做Y,所以你在问这个问题。相反,你最好问问X.你应该告诉我们X是什么。 – Enigmativity

+0

作为最后的手段,您可以创建'Task.Factory.StartNew'的同步匿名委托,并通过'.GetAwaiter()。GetResult()'等待。 – zerkms

+0

@Enigmativity我正在使用'HttpClient'从我正在抓取的网站上下载页面。由于延迟时间很长,我可以将更多的页面并行拖到更好的页面上。这有效,但我希望能够看到任务状态。当运行这个非异步线程在等待'HttpClient'时被阻塞。我试图解决这个问题 –

如何启动任务以等待异步操作?

在TAP中,tasks are returned "hot"。所以你从字面上只需要调用该方法,并保持它的任务返回:

private ConcurrentDictionary<int, Task> Tasks { get; set; } 
private async Task StartTasks() 
{ 
    for(int i = 0; i < 5; i++) 
    { 
    Task task = DoWork(null); 
    Tasks.TryAdd(task.Id, task); 
    } 
} 

我不能使用Task.Run(),因为不提供TaskCreationOptions。这些任务将在字面上运行。

你不需要TaskCreationOptionsThe LongRunning flag is just a hint, and the thread pool will recover within a couple of seconds even if you don't specify that hint。但这并不重要,因为你的工作是异步的,所以它不需要首先在线程池上运行。

+0

我真的很荣幸能获得您的回复,只是在有人将我链接到他们之后阅读您的博客文章。 'The Task = DoWork(null);'正是我在找的东西,谢谢你的解释和链接。 –