Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WinForm如何承载一个长期运行的IronPython脚本,并为进度变化更新UI_C#_Python_Winforms_User Interface_No Response - Fatal编程技术网

C# WinForm如何承载一个长期运行的IronPython脚本,并为进度变化更新UI

C# WinForm如何承载一个长期运行的IronPython脚本,并为进度变化更新UI,c#,python,winforms,user-interface,no-response,C#,Python,Winforms,User Interface,No Response,我需要一个WinForm作为IronPython主机,在IronPython运行时,脚本可以更新UI以报告其进度。我有以下代码,它确实更新了UI,但问题是窗口没有响应。谢谢你的帮助 namespace TryAsyncReport { public partial class Form1 : Form { public Form1() { InitializeComponent(); } /

我需要一个WinForm作为IronPython主机,在IronPython运行时,脚本可以更新UI以报告其进度。我有以下代码,它确实更新了UI,但问题是窗口没有响应。谢谢你的帮助

namespace TryAsyncReport
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        //use python
        private async void button1_Click(object sender, EventArgs e)
        {
            IProgress<ProgressReportInfo> progress = new Progress<ProgressReportInfo>(ReportProgress);
            await Task.Run(() =>
            {
                ScriptEngine engine = Python.CreateEngine();
                ScriptScope scope = engine.CreateScope();
                string script = "for i in range(1000000):\r\n";
                script += "   progress.Report(ProgressReportInfo(i / 10000, str(i / 10000)));\r\n";
                scope.SetVariable("progress", progress);
                scope.SetVariable("ProgressReportInfo", typeof(ProgressReportInfo));
                var code = engine.CreateScriptSourceFromString(script);
                code.Execute(scope);

            });

        }

        private void ReportProgress(ProgressReportInfo info)
        {
            progressBar1.Value = info.Percentage; 
            label1.Text = info.Status; 
        }

    }

    public class ProgressReportInfo
    {
        public ProgressReportInfo(int percentage, string status)
        {
            Percentage = percentage;
            Status = status;
        }
        public int Percentage { set; get; }
        public string Status { set; get; }
    }

}
您必须调用UI线程:

    private void ReportProgress(ProgressReportInfo info)
    {
        // or better BeginInvoke
        Invoke(() =>
        {
            progressBar1.Value = info.Percentage;
            label1.Text = info.Status;
        });
    }
您不需要等待Task.Run

还考虑不报告每一点的进度变化,但让我们说每1000个变化。< /P>


另一种解决方案是使用polling watcher您的脚本更改volatile变量的值,该值在计时器中检查

Thank you Sinatr。但是,当Python运行时,GUI仍然没有响应。请尝试在单独的线程中运行长Python脚本,而不从/向中传递/调用任何内容。这不应该阻止用户界面。如果是这样,那么python Execute就有问题了。也许有一个属性可以通过阻塞/不阻塞调用进程来运行?这个问题是由Python更新UI引起的。如果进展不顺利,请报告。。。被i++替换,问题就消失了。正如您所建议的,我四处寻找Execute的可能属性,但没有结果。实际上,我也尝试了一个后台工作,它显示了相同的行为。如何从python代码中更新UI?我现在明白了,lol,您在那里不是调用ReportProgress,而是调用Report方法。Show please Report方法代码,问题就在这里。progress.Report实际上调用了这个函数private void reportprogressreportinfo