【问题标题】:Abort synchronous method中止同步方法
【发布时间】:2023-01-17 20:18:29
【问题描述】:

是否可以中止长时间执行的同步方法?

我有调用消耗大量内存和 CPU 的 LongRunningMethod 方法的方法测试,以防它持续超过 30 秒,我想中止它。但是抛出异常后,虽然任务完成了,但CPU和内存还在增加。

代码:

static async Task<string> Test (string input)
{
    var tokenSource = new CancellationTokenSource();
    var task = LongRunningMethod(input, tokenSource.Token).WaitAsync(TimeSpan.FromSeconds(30));
    try
    {
        var result = await task;
        return result;
    }
    catch (Exception ex)
    {  
      // if the timeout is thrown, the LongRunningMethod still executes in background and increase memory and cpu
    }
}

static Task<string> LongRunningMethod(string input, CancellationToken token)
{

    var task= Task.Run(() =>
    {
        SynchronousMethodThatConsumesMemoryAndCpu(input);
        return "end";
    },
    token);

    return task;
}

【问题讨论】:

  • 如果不知道 SynchronousMethodThatConsumesMemoryAndCpu 内部发生了什么,这个问题就没有答案。
  • 您的目标是什么 .NET 平台? .NET Core 及更高版本或 .NET Framework?对于 .NET Core,请参阅:.NET Core equivalent to Thread.Abort
  • 我无权访问该方法,它会进行一些转换,但是,我不想优化它或以不同的方式编写它,我想问的是如果我不能传递 CancellationToken 是否可以中止该方法的执行。我的目标是 .NET 6.0

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


【解决方案1】:

我不想优化它或以不同的方式编写它,我想问的是如果我不能传递 CancellationToken 是否可以中止该方法的执行。

不,不容易。没有用于取消/中止不提供取消/中止机制(例如接受令牌)的方法的官方辅助方法。

然而,有一些解决方法,全部使用Thread.Interruptafaik。例如,.NET 性能大师 Stephen Toub 在 2011 年发表了一篇 post,他在其中展示了如何以邪恶的方式做到这一点并解释了它是如何工作的:

我犹豫要不要展示这个 :),但如果你真的想使用中止,你可以这样做:

<1234565 class="剧透">

int Foo(CancellationToken token) {  Thread t = Thread.CurrentThread;  using (token.Register(t.Abort))  {    // compute-bound work here  } } !

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-26
    • 2019-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-18
    相关资源
    最近更新 更多