WinRT一段时间后取消AsyncOperation

时间:2014-10-05 09:25:37

标签: c# windows-runtime async-await

我正在尝试使用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) {

    }
}

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中设置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脚本。

1 个答案:

答案 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());}
}