1

私は現在 C# でアプリケーションを作成しており、外部の VB スクリプトが何らかの方法でアプリケーションの WPF ベースの GUI を操作できるようにしたいと考えています。これらのスクリプトは、非常に長時間実行し、実行中のスレッドを一時停止できるようにする必要があります (これは、実行時に VBScript がビューの内容を決定する小さなスライドショーのようなアプリケーションです)。これを実現するために、ScriptControl COM コンポーネントを参照し、クラスをComVisibleにしました。選択したスクリプトは、次のようにScriptingHostによって実行されます。

public void Run(Action callback)
{
  var thread = new Thread(() =>
  {
    _ScriptControl.Run("Execute", new object[] { }); // _ScriptControl is the COM component
    callback();
  });
  thread.Start();
}

アプリケーションで画像を表示するには、ビュー モデルで次のメソッドを使用します (VBScript から呼び出します)。

public void ShowPicture(string path)
{
  BitmapImage bmImage = new BitmapImage();

  bmImage.BeginInit();
  bmImage.UriSource = new Uri(path, UriKind.Absolute);
  bmImage.EndInit();

  bmImage.Freeze();

  _CurrentImage = bmImage;

  RaisePropertyChanged("CurrentImage");

  // System.Windows.Forms.Application.DoEvents();
}

プロパティCurrentImageは、新しく作成された BitmapImage ( _CurrentImage) を返し、ビューのイメージ コントロールにバインドされます。

スクリプト スレッドを一時停止するスクリプトを実行すると (ユーザーが画像を見る時間を与えるため) 、イベントが発生した後Thread.Sleep()も画像コントロールはCurrentImageプロパティを取得しますが、画像は表示されません。DoEvents呼び出しまたはどこかを追加するとMessageBox.Show、GUI が適切に更新されます。

ShowPicture別のスレッドでメソッドを呼び出し、その後に a が続く画像を表示しようとしましたがThread.Sleep()、これはうまく機能します (ScriptControl COM コンポーネントなし)。

ScriptControl COM コンポーネントは何らかの方法で UI スレッドを使用していますか (私は既に に設定AllowUIしていますfalse)、それとも何か他の不可解な COM 処理が行われているのでしょうか?

スクリプト例:

Function Execute()
    For Each picture In Source.GetPictures(False)
        Canvas.ShowPicture(picture)
        Host.Wait(5) ' Thread.Sleep(5000)
    Next
End Function
4

0 に答える 0