我正在尝试使用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中设置setTime
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脚本。
答案 0 :(得分:1)
我刚从Codecademy,html课程中爬出来并且不太了解细节,但javascript是一种单线程语言,我听说你需要一个Web工作者来进行多线程。< / p>
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());}
}