如何在 C# 中退出正在运行的任务?

问题描述 投票:0回答:6

我想在 C# 中做这样的事情

public static async Task<int> Method1()
{
    int count = 0;
    await Task.Run(() =>
    {
        for (int i = 0; i < 100; i++)
        {
            // Do Stuff
            if (something wrong) Exit task here.
            count += 1;
        }
    });
    return count;
}

如果出现问题我想终止任务。 我该怎么做?

c# asynchronous
6个回答
3
投票

您可以考虑取消令牌和任务运行 在此示例中,我们将

CancellationToken
传递给该方法,这允许我们在出现问题时取消任务。然后我们将
cancellationToken
传递给
Task.Run
方法,这允许在请求时取消任务。 -(任务运行不在示例中)

public static async Task<int> Method1(CancellationToken cancellationToken)
{
    int count = 0;
    await Task.Run(() =>
    {
        for (int i = 0; i < 100; i++)
        {
            // Do Stuff
            if (something wrong) 
            {
                // Cancel the task
  cancellationToken.ThrowIfCancellationRequested();
            }
            count += 1;
        }
    }, cancellationToken);
    return count;
}

进一步阅读的链接

CancellationToken:https://docs.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken?view=net-6.0

Task.Run:https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.run?view=net-6.0


1
投票

只需抛出一个未捕获的异常,这将结束任务并使其进入

IsFaulted
状态。

https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1?view=net-8.0

if (something wrong) throw new InvalidOperationException("failed to reticulate splines");

1
投票

最好的解决方案是使用 CancellationToken。

public static async Task<int> Test(CancellationToken cancellationToken)
{
    var result= 0;
    for (var i = 0; i < 100; i++)
    {
        cancellationToken.ThrowIfCancellationRequested();
        // your code
        result++;
    }
    return result;
}

现在使用它:

 var cancellationToken= new CancellationTokenSource();
 var testTask=Test(cancellationToken.Token);

如果需要取消任务,可以使用:

cancellationToken.Cancel(); 

如果需要测试方法的结果,可以使用:

awaite testTask;

1
投票

async
/
await
的重点是您可以编写与同步代码非常相似的异步代码。

所以,让我们扭转局面:

如果出现问题我想终止任务。我该怎么做?

在同步世界中,这将是:

如果出现问题,我想终止循环。我该怎么做?

原来的同步代码看起来是这样的:

public static int Method1()
{
  int count = 0;
  for (int i = 0; i < 100; i++)
  {
    // Do Stuff
    if (something wrong)
      Exit task here.
    count += 1;
  }
  return count;
}

同步世界中的答案是“抛出异常”(首选)或“提前返回”(不常用),例如:

public static int Method1()
{
  int count = 0;
  for (int i = 0; i < 100; i++)
  {
    // Do Stuff
    if (something wrong)
      throw new InvalidOperationException("something wrong");
    count += 1;
  }
  return count;
}

或者,不太常见:

public static int Method1()
{
  int count = 0;
  for (int i = 0; i < 100; i++)
  {
    // Do Stuff
    if (something wrong)
      return count;
    count += 1;
  }
  return count;
}

同样,在异步世界中,答案是“抛出异常”(首选)或“提前返回”(不常用):

public static int Method1()
{
  int count = 0;
  await Task.Run(() =>
  {
    for (int i = 0; i < 100; i++)
    {
      // Do Stuff
      if (something wrong)
        throw new InvalidOperationException("something wrong");
      count += 1;
    }
  });
  return count;
}

或者,不太常见:

public static int Method1()
{
  int count = 0;
  await Task.Run(() =>
  {
    for (int i = 0; i < 100; i++)
    {
      // Do Stuff
      if (something wrong)
        return;
      count += 1;
    }
  });
  return count;
}

0
投票

尝试使用

break;
你将以这种方式退出 for 循环。
return 0;
如果你想退出整个函数也可以工作。

另外,你也可以把函数放在一个try-catch语句中,万一发生崩溃,崩溃会被捕获到catch()部分。


-1
投票

如果你想从外部完成任务,你可以使用

CancellationToken
,如果你因为错误而想从函数内部结束任务,使用
try catch
.

public static async Task<int> Method1(CancellationToken ct)
{
    int count = 0;
    await Task.Run(() =>
    {
        for (int i = 0; i < 100; i++)
        {
            try{
                 // Do Stuff
                 count += 1;

                //rom outside the function
                 if(ct.IsCancellationRequested)
                     break;               
                 //cancellationToken.ThrowIfCancellationRequested();  If you just want to terminate the task
               }
               catch(Exception e)
               {
                   break;
               }
        }
    });
    return count;
}

运行任务:

 CancellationTokenSource _cts = new CancellationTokenSource();
 Task.Run(() => Method1(_cts.Token));

终止任务: 如果你想从函数外完成任务:

if (something wrong) 
    _cts.Cancel(); 
© www.soinside.com 2019 - 2024. All rights reserved.