一段时间后取消异步操作WinRT
本文关键字:WinRT 异步操作 取消 一段时间 | 更新日期: 2023-09-27 18:25:44
我正在尝试使用WebView
中的Skulpt执行Python脚本。如果python脚本包含一个无限循环,则应用程序不会给出任何响应。
从C#执行Python脚本
await webView.InvokeScriptAsync("evalPy", new string[1] { script });
在JavaScript中:
function evalPy(script) {
try {
var result = Sk.importMainWithBody("<stdin>", false, script);
return Sk.builtins.repr(result).v;
} catch (err) {
}
}
InvokeScriptAsync
是async
操作,可能有某种方法可以在任何时候取消它。
一段时间后,我第一次尝试停止java脚本:
var task = webView.InvokeScriptAsync("evalPy", new string[1] { script }).AsTask<string>();
task.Wait(2000);
task.AsAsyncOperation<string>().Cancel();
第二次尝试:
var op = webView.InvokeScriptAsync("evalPy", new string[1] { script });
new Task(async () =>
{
await Task.Delay(2000);
op.Cancel();
op.Close();
}).Start();
还尝试在JavaScript 中设置超时
function evalPy(script) {
try {
var result = Sk.importMainWithBody("<stdin>", false, script);
setTimeout(function () { throw "Times-out"; }, 2000);
return Sk.builtins.repr(result).v;
} catch (err) {
}
}
CodeSkulptor.org还使用Skulpt在Web浏览器中执行Python脚本,并在一段时间后停止执行Python脚本。
我刚从Codecademy的html课程中爬出来,并不知道详细信息,但javascript是一种单线程语言,我听说你需要一个web工作者来处理多线程。
importScripts('./skulpt.js');
importScripts('./skulpt.min.js');
importScripts('./skulpt-stdlib.js');
// file level scope code gets executed when loaded
// Executed when the function postMessage on
//the worker object is called.
// onmessage must be global
onmessage = function(e){
var out = [];
try{
Sk.configure({output:function (t){out.push(t);}});
Sk.importMainWithBody("<stdin>",false,e.data);
}catch(e){out.push(e.toString());}
postMessage(out.join(''));
}
主页脚本(未测试):
var skulptWorker = new Worker('SkulptWorker.js');
skulptWorker.onmessage = function(e){
//Writing skulpt output to console
console.log(e.data);
running = false;
}
var running = true;
skulptWorker.postMessage('print(''hello world'')');
running = true;
skulptWorker.postMessage('while True:'n print(''hello world'')');
setTimeout(function(){
if(running) skulptWorker.terminate();},5000);
不过,有一个缺点,当我在python代码中使用input()时,skulpt会抛出一个错误,即它在工作线程中找不到窗口对象,我还没有解决方案。
p.s。一些测试显示,下面的代码冻结了主线程(垃圾邮件postMessage是个坏主意):
SkulptWorker.js:
importScripts('./skulpt.js');
importScripts('./skulpt.min.js');
importScripts('./skulpt-stdlib.js');
// file level scope code gets executed when loaded
// Executed when the function postMessage on
//the worker object is called.
// onmessage must be global
onmessage = function(e){
try{
Sk.configure({output:function (t){postMessage(t);}});
Sk.importMainWithBody("<stdin>",false,e.data);
}catch(e){postMessage(e.toString());}
}