2014-10-05 76 views
0

我试图在WebView中使用Skulpt执行Python脚本。如果python脚本包含无限循环应用程序没有响应。在一段时间后取消异步操作WinRT

从C#

await webView.InvokeScriptAsync("evalPy", new string[1] { script }); 

执行Python脚本的JavaScript:

function evalPy(script) { 
    try { 
     var result = Sk.importMainWithBody("<stdin>", false, script); 
     return Sk.builtins.repr(result).v; 
    } catch (err) { 

    } 
} 

InvokeScriptAsyncasync操作可能会有一些办法来取消它的任何一点。

我第一次尝试了一段时间后停止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的setTimeout

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脚本并停止执行P.一段时间后,ython脚本。

+0

当你'await',该方法不会返回给JavaScript,直到执行做完了。因此无限循环将永远不会返回。当你等待两秒钟然后取消会发生什么? – 2014-10-05 09:31:53

+0

当我等待两秒钟后取消,无限循环继续。调试器将任务状态显示为已取消,但应用程序不响应 – 2014-10-05 09:42:24

+0

python进程将继续执行,但应返回方法调用。你正在做方法调用中的其他任何东西吗? – 2014-10-05 09:47:41

回答

1

我刚刚爬出了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代码中使用的输入(),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());} 
}