2014-10-05 113 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());} 
}