C# WPF UI 在 C# 中调用 IronPython 时冻结 Visual Studio

C# WPF UI Freezes when calling IronPython inside C# Visual Studio

我刚刚用C#写了一个程序,做了一个ui,并在里面集成了ironpython来做一些计算。 但是当我调用函数时 UI 冻结直到函数结束(甚至进度条冻结)

如果这个问题很愚蠢,请原谅我,因为这是我在 whosebug.com

上的第一个问题

函数是:

private void ValidateB_Click(object sender, RoutedEventArgs e)
{
    string txt = proInp.Text;
    var eng = Python.CreateEngine();
    var searchPaths = eng.GetSearchPaths();
    searchPaths.Add("F:\Python27\Lib");
    searchPaths.Add("F:\Python 3.6\Lib");
    eng.SetSearchPaths(searchPaths);
    var scope = eng.CreateScope();
    scope.SetVariable("key", txt);
    eng.Execute("import os\nkey="os.getcwd()", scope);
}

解决此问题的一个简单方法是使点击处理程序异步并运行一个新任务(但是如果您有任何不应在任务内完成的 GUI 交互):

private async void ValidateB_Click(object sender, RoutedEventArgs e)
{
   await Task.Factory.StartNew(() => {
       string txt = proInp.Text;
       var eng = Python.CreateEngine();
       var searchPaths = eng.GetSearchPaths();
       searchPaths.Add("F:\Python27\Lib");
       searchPaths.Add("F:\Python 3.6\Lib");
       eng.SetSearchPaths(searchPaths);
       var scope = eng.CreateScope();
       scope.SetVariable("key", txt);
       eng.Execute("import os\nkey="os.getcwd()", scope);
   }
}

但最好与异步命令和绑定一起使用。可以阅读有关 WPF 和 MMVM 的内容以了解其工作原理。

我建议使用不等待的 TAP 模式 (Task-based Asynchronous Pattern)(因为您想立即响应 UI),如下所示:

    private void ValidateB_Click(object sender, RoutedEventArgs e)
    {
        Task t = Task.Factory.StartNew(() =>
        {
            string txt = proInp.Text;
            var eng = Python.CreateEngine();
            var searchPaths = eng.GetSearchPaths();
            searchPaths.Add("F:\Python27\Lib");
            searchPaths.Add("F:\Python 3.6\Lib");
            eng.SetSearchPaths(searchPaths);
            var scope = eng.CreateScope();
            scope.SetVariable("key", txt);
            eng.Execute("import os\nkey="os.getcwd()", scope);
        });
    }