简体   繁体   English

执行长时间运行的任务时,显示进程表单的 c# 似乎卡住了

[英]c# showing a process form seems to get stuck when performing a long running task

I am in the process of creating a POS system using C# and WinForms.我正在使用 C# 和 WinForms 创建 POS 系统。

I am using a form with some text and an image to indicate when a long running process is performed, like sales printing and DB update after the sale.我正在使用带有一些文本和图像的表单来指示何时执行长时间运行的过程,例如销售打印和销售后的数据库更新。 But when I do that, only the AjaxLoader form is showing and it's not calling the update functions below it.但是当我这样做时,只显示AjaxLoader表单并且它没有调用它下面的更新函数。

This is my code.这是我的代码。

public void completeSale()//invoked on Sell button
{
    
    loader = new AjaxLoader();//this is a form
    loader.label1.Text = "Printing...";
    ThreadStart threadStart = new ThreadStart(Execution);
    Thread thread = new Thread(threadStart);
    thread.SetApartmentState(ApartmentState.STA);
    thread.Start();
}

private void Execution()
{
    this.Invoke((MethodInvoker)delegate { loader.ShowDialog(this); });
    Application.DoEvents();

    update_sale("Sold");//method not getting called at all

    this.Invoke((MethodInvoker)delegate { loader.Dispose(); });
}

This is my Ajax loader form that I need to display, that is supposed to block my POS form.这是我需要显示的 Ajax 加载程序表单,它应该阻止我的 POS 表单。 So upon finishing the printing (doing background task) I need to close the loader.所以在完成打印(做后台任务)后,我需要关闭加载器。

Ajax 加载器

The problem is that the lines问题是线条

Application.DoEvents();
update_sale("Sold");//method not getting called at all

is never reached.永远不会到达。

What am I doing wrong?我究竟做错了什么?

The .ShowDialog() on a form is a blocking call, so your code will wait until the form that is shown as dialog is .Closed()表单上的.ShowDialog()是一个阻塞调用,因此您的代码将等到显示为对话框的表单为.Closed()

I would also recommend using using async Task as this makes working with Threads much much easier!我还建议使用async Task因为这使得使用Threads更容易!

I've changed your code to show this.我已经更改了您的代码以显示这一点。

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

    private async void button1_Click(object sender, EventArgs e)
    {
        await completeSale();
    }

    AjaxLoader loader = null;
    public async Task completeSale()//invoked on Sell button
    {
         //for info, this is how I set up AjaxLoader form properties in the designer.
         loader = new AjaxLoader();
         loader.label1.Text = "Printing...";
         loader.TopMost = true;
         loader.WindowState = FormWindowState.Normal;
         loader.StartPosition = FormStartPosition.CenterParent;
         loader.ShowInTaskbar = false;
         loader.ControlBox = false;
         loader.FormBorderStyle = FormBorderStyle.None;
        //loader.PointToClient(this.DesktopLocation);

        await Execution();   
    }

    private async Task Execution()
    {
        
        if (loader.InvokeRequired)
            this.Invoke((MethodInvoker)delegate { loader.Show(this); });
        else
            loader.Show(this);
        //Application.DoEvents();

        await update_sale("Sold");

        if (loader.InvokeRequired)
            this.Invoke((MethodInvoker)delegate { loader.Close(); });
        else
            loader.Close();
        
    }

    private async Task update_sale(string v)
    {
        //long running process like printing etc..
        await Task.Delay(3000);
    }
}

this will do something like this:这会做这样的事情:

在此处输入图片说明

On the AjaxLoader form I added a progress bar that is set to style = Marquee在 AjaxLoader 表单上,我添加了一个设置为style = Marquee的进度条

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM