我目前正在用 C# 编写一个应用程序,并希望允许外部 VB 脚本以某种方式操作应用程序的基于 WPF 的 GUI。应该允许这些脚本运行很长时间并暂停它们正在运行的线程(这是一个类似于幻灯片的应用程序,其中 VBScripts 在运行时确定视图的内容)。为此,我引用了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
在单独的线程中显示调用该方法的图像,然后是 aThread.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