2016-07-21 44 views
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; 
    } 
} 

回答

1

在您的測試()方法添加在您傳遞的CancellationToken到腳本的參數。然後設計腳本中的循環來檢查canellation標記,如果中止已被請求併發生。要停止腳本,只需調用CancellationTokenSource的Cancel()方法,即在調用時傳遞給腳本的令牌。

+0

沒有幫助,如果我的用戶dosn't檢查在他的腳本。 – MTR

+1

然後,不要讓腳本中的while,foreach等(即通過正則表達式檢查和拒絕),並提供這些循環結構的安全可中止版本,這些循環結構需要一個委託並像其替換的循環一樣工作。 另一個想法但不太容易實現的方法是通過插入if(token.IsCancelled)return的IL-等價來修改生成的IL;或在每個循環的開始處類似。如果您在DEBUG模式下編譯腳本,循環的開始很容易在調試程序中發現,因爲它以兩個連續的非操作指令開始。 – henon

+0

替換循環的好主意。我想我會走這條路。 – MTR