标签: cancellationtokensource

在键盘事件中使用CancellationToken调用Task.Delay时的TaskCanceledException

我试图延迟在WinRT中从键盘事件调用的方法(在示例中为SubmitQuery())的处理,直到一段时间内没有其他事件(在这种情况下为500毫秒).

我只想在我认为用户输入完成后运行SubmitQuery().

使用下面的代码,当Task.Delay(500,cancellationToken.Token)时,我不断收到System.Threading.Tasks.TaskCanceledException; 叫做.我在这做错了什么?

CancellationTokenSource cancellationToken = new CancellationTokenSource();

private async void SearchBox_QueryChanged(SearchBox sender, SearchBoxQueryChangedEventArgs args)
{

        cancellationToken.Cancel();
        cancellationToken = new CancellationTokenSource();

    await Task.Delay(500, cancellationToken.Token);

    if (!cancellationToken.IsCancellationRequested)
    {
        await ViewModel.SubmitQuery();
    }
}
Run Code Online (Sandbox Code Playgroud)

c# asynchronous cancellationtokensource windows-runtime cancellation-token

16
推荐指数
4
解决办法
8084
查看次数

如何将AbortController与Axios和React集成?

Abortcontroller 信号不适用于 React 中的 Axios。

我想用 AbortController 替换 CancelToken (因为它已被弃用),但它不起作用,分别是请求没有被取消。

  let testController: AbortController;

  function loadTest() {
    testController = new AbortController();

    TestAPI.getTest(testController.signal)
      .then((e) => {
        console.log(e.data);
      })
      .catch((e) => {
        console.error(e);
      });
  }
Run Code Online (Sandbox Code Playgroud)

同样在 UseEffect Cleanup 中,我执行了此操作(这里应该取消),并且信号的状态也设置为中止,但请求仍然没有取消:

  useEffect(() => () => {
    if (testController) testController.abort();
    // console.log(testController.signal.aborted) => **true**
  }, []);
Run Code Online (Sandbox Code Playgroud)

这是我的 API,我将 AbortSignal 传递给请求:

  getTest(signal?: AbortSignal): Promise<AxiosResponse<Test[]>> {
    return axios.get(`${URI}/test`, { signal });
  },
Run Code Online (Sandbox Code Playgroud)

使用 Axios.CancelToken.source 时工作正常,但现在使用 AbortController,请求永远不会被取消。

使用:“axios”:“^ 0.26.0 ”,

有人设法将 AbortController 与 React 和 Axios 集成吗?或者 AbortController只 …

cancellation cancellationtokensource reactjs react-native axios

16
推荐指数
2
解决办法
4万
查看次数

使用CancellationToken取消SQL Server查询

我在SQL Server中有一个长期运行的存储过程,我的用户需要能够取消它.我写了一个小测试应用程序,如下所示,该SqlCommand.Cancel()方法可以很好地运行:

    private SqlCommand cmd;
    private void TestSqlServerCancelSprocExecution()
    {
        TaskFactory f = new TaskFactory();
        f.StartNew(() =>
            {
              using (SqlConnection conn = new SqlConnection("connStr"))
              {
                conn.InfoMessage += conn_InfoMessage;
                conn.FireInfoMessageEventOnUserErrors = true;
                conn.Open();

                cmd = conn.CreateCommand();
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.CommandText = "dbo.[CancelSprocTest]";
                cmd.ExecuteNonQuery();
              }
           });
    }

    private void cancelButton_Click(object sender, EventArgs e)
    {
        if (cmd != null)
        {
            cmd.Cancel();
        }
    }
Run Code Online (Sandbox Code Playgroud)

在调用时cmd.Cancel(),我可以验证基础存储过程基本上立即停止执行.鉴于我在我的应用程序中使用了异步/等待模式,我希望SqlCommand采用CancellationToken参数的异步方法同样可以正常工作.不幸的是,我发现,呼吁Cancel()CancellationToken造成InfoMessage事件处理程序不再被调用,但底层的存储过程继续执行.我的异步版本的测试代码如下:

    private SqlCommand cmd;
    private CancellationTokenSource cts; …
Run Code Online (Sandbox Code Playgroud)

c# sql-server async-await cancellationtokensource

14
推荐指数
1
解决办法
8375
查看次数

如何将CancellationTokenSource附加到DownloadStringTaskAsync方法并取消异步调用?

我创建了一个示例示例,使用async和await方法使用WebClient调用链接现在我想附加取消异步调用功能.但我无法获得CancellationTokenSource令牌并将DownloadStringTaskAsync附加到此取消令牌.以下是我的代码可以告诉我如何实现这一目标.

private async void DoWork()
        {
            this.Cursor = Cursors.WaitCursor;
            Write("DoWork started.");
            cts = new CancellationTokenSource();
            WebClient wc = new WebClient();
            string result = await wc.DownloadStringTaskAsync(new Uri("http://gyorgybalassy.wordpress.com"));

            if (result.Length < 100000)
            {
                Write("The result is too small, download started from second URL.");
                result = await wc.DownloadStringTaskAsync(new Uri("https://www.facebook.com/balassy"));
            }
            Write("Download completed. Downloaded bytes: " + result.Length.ToString());
            Write("DoWork ended.");
            this.Cursor = Cursors.Default;
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            Write("Cancellation started.");
            this.cts.Cancel();
            Write("Cancellation ended.");
        }
Run Code Online (Sandbox Code Playgroud)

当我的取消按钮调用cts.Cancel时,不会取消DownloadStringTaskAsync调用.为什么取消按钮无法取消异步通话?

c# async-await c#-5.0 cancellationtokensource .net-4.5

13
推荐指数
2
解决办法
4448
查看次数

Task.Factory.FromAsync with CancellationTokenSource

我有以下代码行用于从NetworkStream异步读取:

int bytesRead = await Task<int>.Factory.FromAsync(this.stream.BeginRead, this.stream.EndRead, buffer, 0, buffer.Length, null);
Run Code Online (Sandbox Code Playgroud)

我想支持取消.我看到我可以使用CancellationTokenSource取消任务,但是我没有看到任何方法可以将它传递给TaskFactory.FromAsync().

是否可以使FromAsync()构造的任务支持取消?

编辑:我想取消已经运行的任务.

c# task task-parallel-library cancellationtokensource

13
推荐指数
3
解决办法
3938
查看次数

是否在任务取消时正确处理CancellationTokenSource的代码?

我在我面前看到这个代码,我很怀疑:

CancellationTokenSource _cts;

public void Dispose();
{
    _cts.Cancel();
    _cts.Dispose();
    _task.Wait(); //wait for the task to be canceled!?
}
Run Code Online (Sandbox Code Playgroud)

取消后直接调用_cts.Dispose()是否安全?如果想要这样做,是否会取消取消任务所需的CancellationTokenSource的底层资源以成功等待CancellationToken?

.net c# cancellationtokensource

13
推荐指数
1
解决办法
2688
查看次数

对CancellationTokenSource.Cancel的调用永远不会返回

我有一种CancellationTokenSource.Cancel永远不会回来的情况.相反,在Cancel调用之后(并且在它返回之前),执行继续执行被取消的代码的取消代码.如果取消的代码随后不会调用任何等待代码,则最初调用的调用者Cancel永远不会获得控制权.这很奇怪.我希望Cancel只记录取消请求并立即独立返回取消本身.Cancel被调用的线程最终会执行属于正在被取消的操作的代码,并且在返回到Cancel看起来像框架中的错误的调用者之前这样做.

以下是这样的:

  1. 有一段代码,我们称之为"工作代码",它正在等待一些异步代码.为了简单起见,我们假设这段代码正在等待Task.Delay:

    try
    {
        await Task.Delay(5000, cancellationToken);
        // … 
    }
    catch (OperationCanceledException)
    {
        // ….
    }
    
    Run Code Online (Sandbox Code Playgroud)

就在"工作者代码"调用之前,Task.Delay它正在线程T1上执行.继续(即"await"之后的行或catch中的块)将在T1或者某些其他线程上执行,具体取决于一系列因素.

  1. 还有另一段代码,我们称之为"客户端代码",决定取消该代码Task.Delay.这段代码叫cancellationToken.Cancel.调用Cancel是在线程T2上进行的.

我希望线程T2继续返回到调用者Cancel.我还希望catch (OperationCanceledException)在线程T1或T2之外的某些线程上看到很快执行的内容.

接下来发生的事情令人惊讶.我在线程T2上看到,在Cancel调用之后,执行会立即继续执行catch (OperationCanceledException).当这Cancel仍然在callstack上时会发生这种情况.好像呼叫Cancel被代码劫持它被取消了.这是Visual Studio的屏幕截图,显示了这个调用堆栈:

调用堆栈

更多背景

下面是关于实际代码的更多上下文:有一个"工作代码"可以累积请求.某些"客户端代码"正在提交请求.每隔几秒"工作代码"就会处理这些请求.处理的请求将从队列中删除.然而,偶尔,"客户端代码"决定它到达希望立即处理请求的点.为了将其传达给"工人代码",它调用Jolt"工人代码"提供的方法.Jolt"客户端代码"调用的方法通过取消Task.Delay由工作者代码主循环执行的方法来实现此功能.工作人员的代码已Task.Delay取消,并继续处理已排队的请求.

实际代码被拆分为最简单的形式,代码可以在GitHub上获得.

环境

该问题可以在控制台应用程序,Universal Apps for Windows的后台代理和适用于Windows Phone 8.1的Universal Apps的后台代理中重现.

该问题无法在Windows的通用应用程序中重现,其中代码按照我的预期运行,并且调用Cancel立即返回.

c# asynchronous task async-await cancellationtokensource

11
推荐指数
2
解决办法
2364
查看次数

任何区分取消和超时的方法

我有一些代码通过调用许多其他服务来验证某些数据.我并行启动所有调用,然后等到其中至少一个完成.如果任何请求失败,我不关心其他调用的结果.

我打电话,HttpClient我已经通过了HttpMessageHandler一个记录.实质上:

protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
    HttpResponseMessage response = null;

    try
    {
        response = await base.SendAsync(request, cancellationToken);
    }
    catch (OperationCanceledException ex)
    {
        LogTimeout(...);
        throw;
    }
    catch (Exception ex)
    {
        LogFailure(...);
        throw;
    }
    finally
    {
        LogComplete(...);
    }

    return response;
}
Run Code Online (Sandbox Code Playgroud)

当我取消请求时,我遇到麻烦的部分没有.当我取消请求时,我是故意这样做的,所以我不希望它被记录为超时,但是在取消和实际超时之间似乎没有任何区别.

反正有没有完成这个?

编辑: 我需要澄清一下这一点.并行调用的服务是使用超时传递CancellationTokens:

var ct = new CancellationTokenSource(TimeSpan.FromSeconds(2));
Run Code Online (Sandbox Code Playgroud)

因此,当服务器响应时间超过两秒时,我得到一个OperationCanceledException,如果我手动取消令牌源(比如因为另一台服务器在1秒后返回错误),那么我仍然得到一个OperationCanceledException.理想情况下,我将能够看到CancellationToken.IsCancellationRequested以确定它是否被取消,由于超时,而不是明确要求被取消,但现在看来,你得到相同的值,而不管怎么就被取消了.

c# http cancellation cancellationtokensource dotnet-httpclient

11
推荐指数
2
解决办法
3307
查看次数

CancellationTokenSource与Task循环退出的退出标志之间的区别

我想知道结束循环任务与CancellationTokenSource和退出标志之间是否有任何区别

CancellationTokenSource:

CancellationTokenSource cancellationTokenSource;
Task loopTask;

void StartLoop()
{
    cancellationTokenSource = new CancellationTokenSource();
    loopTask = Task.Factory.StartNew(Loop, TaskCreationOptions.LongRunning);
}

void Loop()
{
    while (true)
    {
        if (cancellationTokenSource.IsCancellationRequested)
            break;

        Thread.Yield();
    }
}

void StopLoop()
{
    cancellationTokenSource.Cancel();

    loopTask = null;
    cancellationTokenSource = null;
}
Run Code Online (Sandbox Code Playgroud)

退出标志:

volatile bool exitLoop;
Task loopTask;

void StartLoop()
{
    exitLoop = false;
    loopTask = Task.Factory.StartNew(Loop, TaskCreationOptions.LongRunning);
}

void Loop()
{
    while (true)
    {
        if (exitLoop)
            break;

        Thread.Yield();
    }
}

void StopLoop()
{
    exitLoop = true;

    loopTask = null;
} …
Run Code Online (Sandbox Code Playgroud)

.net c# task exit cancellationtokensource

10
推荐指数
1
解决办法
899
查看次数

默认(CancellationToken)如何具有相应的CancellationTokenSource

当我创建一个默认的CancellationToken,我可以在该调试器中看到CancellationToken有一个CancellationTokenSource与它存储在私有关联的m_source领域:

不是空的

我想知道如何对于结构default关键字"将返回结构的每个成员初始化为零或取决于它们是值还是引用类型"并且CancellationTokenSource是引用类型.

CancellationToken确实有2个构造函数设置这个字段然而它们是不相关的,因为default(CancellationToken)不调用构造函数和new CancellationToken()(它具有完全相同的行为)不会调用构造函数,因为结构不能有无参数构造函数(尚未).

.net c# cancellationtokensource cancellation-token

10
推荐指数
1
解决办法
1854
查看次数