我试图延迟在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
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
我在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) 我创建了一个示例示例,使用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调用.为什么取消按钮无法取消异步通话?
我有以下代码行用于从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()构造的任务支持取消?
编辑:我想取消已经运行的任务.
我在我面前看到这个代码,我很怀疑:
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?
我有一种CancellationTokenSource.Cancel
永远不会回来的情况.相反,在Cancel
调用之后(并且在它返回之前),执行继续执行被取消的代码的取消代码.如果取消的代码随后不会调用任何等待代码,则最初调用的调用者Cancel
永远不会获得控制权.这很奇怪.我希望Cancel
只记录取消请求并立即独立返回取消本身.Cancel
被调用的线程最终会执行属于正在被取消的操作的代码,并且在返回到Cancel
看起来像框架中的错误的调用者之前这样做.
以下是这样的:
有一段代码,我们称之为"工作代码",它正在等待一些异步代码.为了简单起见,我们假设这段代码正在等待Task.Delay:
try
{
await Task.Delay(5000, cancellationToken);
// …
}
catch (OperationCanceledException)
{
// ….
}
Run Code Online (Sandbox Code Playgroud)就在"工作者代码"调用之前,Task.Delay
它正在线程T1上执行.继续(即"await"之后的行或catch中的块)将在T1或者某些其他线程上执行,具体取决于一系列因素.
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
立即返回.
我有一些代码通过调用许多其他服务来验证某些数据.我并行启动所有调用,然后等到其中至少一个完成.如果任何请求失败,我不关心其他调用的结果.
我打电话,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
我想知道结束循环任务与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) 当我创建一个默认的CancellationToken
,我可以在该调试器中看到CancellationToken
有一个CancellationTokenSource
与它存储在私有关联的m_source
领域:
我想知道如何对于结构default
关键字"将返回结构的每个成员初始化为零或取决于它们是值还是引用类型"并且CancellationTokenSource
是引用类型.
CancellationToken
确实有2个构造函数设置这个字段然而它们是不相关的,因为default(CancellationToken)
不调用构造函数和new CancellationToken()
(它具有完全相同的行为)不会调用构造函数,因为结构不能有无参数构造函数(尚未).
c# ×9
.net ×3
async-await ×3
task ×3
asynchronous ×2
cancellation ×2
.net-4.5 ×1
axios ×1
c#-5.0 ×1
exit ×1
http ×1
react-native ×1
reactjs ×1
sql-server ×1