首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >具有活动UI并在后台运行1线程的Winform

具有活动UI并在后台运行1线程的Winform
EN

Stack Overflow用户
提问于 2016-06-03 19:30:56
回答 1查看 177关注 0票数 0

我有一个Winforms应用程序,它通过它的API调用CorelDraw,然后在保存映像之前做一些工作。我尝试使用线程、BackgroundWorker和继承了BackgroundWorker但也允许使用Thread.Abort的类来设置它。每做一次工作,我都会遇到两个问题中的一个。要么线程不在后台运行,在这种情况下,由于窗体被冻结,我无法在窗体上按下任何按钮,要么线程在后台运行,但在我第一次调用CorelDraw时立即停止处理。

有没有其他的解决办法?我们处理这个问题的老方法是让一个观察者WinForm生成另一个Process(),它可以在CorelDraw中完成所有事情。使用Process()调用的进程将重要信息保存到.txt文件中,供父进程检查,如果子进程在同一图像上工作时间过长,父进程将在其父进程上调用Kill()。到目前为止,这是一个笨重和容易出错的方式来做事情,这就是为什么我正在寻找一个更好的解决方案。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-06-05 03:17:29

设计师代码:

代码语言:javascript
复制
namespace Tasks
{
    partial class Form1
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.button1 = new System.Windows.Forms.Button();
            this.button2 = new System.Windows.Forms.Button();
            this.SuspendLayout();
            // 
            // button1
            // 
            this.button1.Location = new System.Drawing.Point(41, 43);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(75, 23);
            this.button1.TabIndex = 0;
            this.button1.Text = "button1";
            this.button1.UseVisualStyleBackColor = true;
            this.button1.Click += new System.EventHandler(this.button1_Click);
            // 
            // button2
            // 
            this.button2.Location = new System.Drawing.Point(131, 43);
            this.button2.Name = "button2";
            this.button2.Size = new System.Drawing.Size(75, 23);
            this.button2.TabIndex = 1;
            this.button2.Text = "button2";
            this.button2.UseVisualStyleBackColor = true;
            this.button2.Click += new System.EventHandler(this.button2_Click);
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(240, 116);
            this.Controls.Add(this.button2);
            this.Controls.Add(this.button1);
            this.Name = "Form1";
            this.Text = "Form1";
            this.ResumeLayout(false);

        }

        #endregion

        private System.Windows.Forms.Button button1;
        private System.Windows.Forms.Button button2;
    }
}

这是表单代码:

代码语言:javascript
复制
using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Tasks
{
    public partial class Form1 : Form
    {
        CancellationTokenSource cts;

        public Form1()
        {
            InitializeComponent();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            MessageBox.Show(this,"This button still works :)");
        }

        private async void button1_Click(object sender, EventArgs e)
        {
            cts = new CancellationTokenSource();

            await CreateTask();
        }

        private async Task CreateTask()
        {
            //Create a progress object that can be used within the task
            Progress<string> mProgress; //you can set this to Int for ProgressBar
            //Set the Action to a function that will catch the progress sent within the task
            Action<string> progressTarget = ReportProgress;
            //Your new Progress with the included action function
            mProgress = new Progress<string>(progressTarget); 

            //start your task
            string result = await MyProcess(mProgress);
        }

        private Task<string> MyProcess(IProgress<string> myProgress)
        {
            return Task.Run(() =>
            {
                //To report Progress back to your UI thread
                myProgress.Report("Starting program now...");
                //Start your Corel Draw program here.
                Process.Start("C:\\WINDOWS\\system32\\notepad.exe").WaitForExit();
                //You can return the Image after your done editing it
                return "Program has been closed";

            }, cts.Token);
        }

        private void ReportProgress(string message)
        {
            //typically to update a progress bar or whatever
            MessageBox.Show(this, message);
        }
    }
}

如果您创建异步任务,您可以在后台运行Corel应用程序,然后当它关闭时,它将完成任务。我在其中添加了额外的内容,比如“进度”和“cts”,用于在父窗口关闭时取消该任务。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37622074

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档