我正在尝试从 C# 取消用 C++/CX 编写的操作。尽管我编写了这两段代码,但在从 C# 端等待操作时,我无法正确取消该操作。这是一个例子:
来自 C#:
var tcs = new CancellationTokenSource();
tcs.Cancel();
var class1 = new MyClass();
try
{
var asyncOp = await class1.DoSomeTaskAsync().AsTask(tcs.Token);
}
catch (OperationCanceledException oce)
{
//I want to get here
Handle(oce);
}
来自 C++:
IAsyncOperation<bool>^ MyClass::DoSomeTaskAsync(){
return concurrency::create_async([](concurrency::cancellation_token ct) {
task<bool> my_task([]() {
doSomething1();
if (concurrency::is_task_cancellation_requested())
{
concurrency::cancel_current_task();
}
doSomething2();
return false;
}, ct);
return my_task;
});
}
问题似乎是,在跨 ABI 调用任务时,将 token 传递到 AsTask 扩展方法中不会执行任何操作。在调试 C++ 端时,ct 和 is_task_cancellation_requested() 函数均指示尚未请求取消。
最佳答案
试试这个。在您的 C++ Windows 运行时组件中执行一些需要很长时间的操作,例如,concurrency::wait(2000)
将使线程休眠两秒钟(不要在真实的应用程序中执行此操作)。
#include <ppltasks.h>
using namespace Windows::Foundation;
IAsyncOperation<bool>^ MyClass::DoSomeTaskAsync()
{
return concurrency::create_async([=](concurrency::cancellation_token token)
{
// Do something.
concurrency::wait(2000);
if (concurrency::is_task_cancellation_requested())
{
concurrency::cancel_current_task();
}
// Do something else.
concurrency::wait(2000);
return true;
});
}
然后,在您的 C# Windows 应用商店应用程序中创建两个按钮:
<Button x:Name="DoButton" Click="DoButton_Click">Do</Button>
<Button x:Name="CancelButton" Click="CancelButton_Click">Cancel</Button>
在Do按钮中调用组件的异步方法。
private System.Threading.CancellationTokenSource cts;
private async void DoButton_Click(object sender, RoutedEventArgs e)
{
cts = new System.Threading.CancellationTokenSource();
var class1 = new MyClass();
try
{
var asyncOp = await class1.DoSomeTaskAsync().AsTask(cts.Token);
System.Diagnostics.Debug.WriteLine(asyncOp);
}
catch (OperationCanceledException oce)
{
// I want to get here.
System.Diagnostics.Debug.WriteLine(oce);
}
}
并在取消按钮中取消操作。
private void CancelButton_Click(object sender, RoutedEventArgs e)
{
cts.Cancel();
cts = null;
}
运行应用程序,单击Do
按钮,然后在两秒钟内单击Cancel
按钮。您应该得到一个System.Threading.OperationCanceledException
。
关于c# - 如何从 C# 取消 C++/CX 中的异步操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21610005/