0
我使用CS腳本庫在我的WPF應用程序中運行用戶定義的腳本。如果腳本無限運行,我該如何取消腳本?當我的用戶編寫腳本時,我不能依賴腳本中檢查的取消標誌。如何停止使用CSScript加載的腳本?
下面是該問題的一個簡化的代碼片段:
public partial class MainWindow : Window
{
public string MessageFromScript
{
get { return (string)GetValue(MessageFromScriptProperty); }
set { SetValue(MessageFromScriptProperty, value); }
}
public static readonly DependencyProperty MessageFromScriptProperty =
DependencyProperty.Register("MessageFromScript", typeof(string), typeof(MainWindow), new PropertyMetadata(null));
public MainWindow()
{
InitializeComponent();
DataContext = this;
}
BackgroundWorker worker = null;
private void OnStart(object sender, RoutedEventArgs e)
{
if(worker != null)
{
return;
}
worker = new BackgroundWorker();
worker.DoWork += RunScript;
worker.RunWorkerCompleted += ScriptCompleted;
worker.WorkerSupportsCancellation = true;
worker.RunWorkerAsync();
}
private void ScriptCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if(e.Cancelled)
MessageFromScript = "Script cancelled";
else
MessageFromScript = e.Result.ToString();
}
private void RunScript(object sender, DoWorkEventArgs e)
{
dynamic script = CSScript.Evaluator.LoadCode(@"using System;
using System.Threading;
public class Script
{
public string Test()
{
{int count=0; while(true) { count++; Console.WriteLine(count.ToString()); Thread.Sleep(200); }}
return ""Message from script"";
}
}");
e.Result = script.Test();
}
private void OnStop(object sender, RoutedEventArgs e)
{
if(worker == null)
{
return;
}
//TODO: How do I stop the script here?
worker = null;
}
}
沒有幫助,如果我的用戶dosn't檢查在他的腳本。 – MTR
然後,不要讓腳本中的while,foreach等(即通過正則表達式檢查和拒絕),並提供這些循環結構的安全可中止版本,這些循環結構需要一個委託並像其替換的循環一樣工作。 另一個想法但不太容易實現的方法是通過插入if(token.IsCancelled)return的IL-等價來修改生成的IL;或在每個循環的開始處類似。如果您在DEBUG模式下編譯腳本,循環的開始很容易在調試程序中發現,因爲它以兩個連續的非操作指令開始。 – henon
替換循環的好主意。我想我會走這條路。 – MTR