首页 > 解决方案 > 创建/初始化任务而不立即启动它

问题描述

我想从异步 Task 方法创建/初始化一个 Task 对象,而不直接启动它。在线搜索时,我只能找到从 void 方法创建的任务的答案。

这是我要执行的任务方法。由于我需要异步执行一些 Web 请求,因此该方法需要是异步的。我也想做异常处理,所以它不能是async void.

private async Task WebRequestTask()
{
    try
    {
        string ResponseText = await httpClient.GetStringAsync("https://fakeurl.com");
        // process response code
    }
    catch (Exception ex)
    {
         // handle error
    }
}

这是我要创建任务的主要方法:

private void StartTask()
{
    TokenSource = new CancellationTokenSource();
    Task RequestTask = ... // here I want to initialize the task without starting

    // chain continuation tasks to RequestTask

    RequestTask.Start();
}

我尝试了以下解决方案,但没有满足我的需求:

解决方案 1

Task RequestTask = new Task(WebRequestTask); 
Task RequestTask = WebRequestTask;

-> 两者都会导致编译器错误

解决方案 2

Task RequestTask = Task.Run(WebRequestTask);

-> 这将启动任务异步并且当前方法继续(但这里可能会在连续任务被链接之前引发异常)

解决方案 3

Task RequestTask = WebRequestTask(); 

-> 这会同步启动任务,并在任务完成后发生链接

解决方案 4

Task<Task> OuterTask = new Task<Task>(LoginToAzure);
await LoginAzureTask.Unwrap();

-> 这会启动外部任务,但内部任务永远不会被调用

如何将此 Task 方法附加到 Task 对象,以便我可以先附加延续任务/设置一些选项然后启动它?如果可能的话,我也想使用取消令牌。

标签: c#asynchronousmvvm

解决方案


我也想做异常处理,所以它不能是async void.

由于您正在处理 WebRequestTask() 中的错误,这并不重要。

首选的选项是使 StartTask 成为一个,async Task但如果这不可能,请使它成为async void. 这也照顾了“没有开始”的要求。

所以,保持简单:

private async void StartTask()
{
    TokenSource = new CancellationTokenSource();

    try
    {
      await WebRequestTask(TokenSource.Token);

      // here I want to initialize the task without starting -- irrelevant in an async void

      await otherTask();  // continuation(s)
    }
    catch()
    {
       // handle residual errors
    }   
}

推荐阅读