当CSV被错误检查时,我如何显示加载/启动屏幕- C# WinForms?

0yycz8jy  于 2023-05-18  发布在  C#
关注(0)|答案(2)|浏览(135)

我有一个C# WindowsForm应用程序,它可以读取CSV文件并过滤掉文件中出现的任何“错误”。然后,应用程序允许用户通过特定过滤器(即,过滤错误后,将显示表单。然而,这需要几秒钟。在此期间,我想显示一个启动/加载屏幕,以显示应用程序正在加载。
我已经创建了一个显示启动屏幕的线程,但是,下面显示的代码中抛出了以下错误。
System.ComponentModel. InvalidAssynchronousStateException:'调用方法时出错。目标线程不再存在。

private void UpdateLabel(object sender, ElapsedEventArgs e)
        {
            if (Thread.CurrentThread.IsAlive)
            {
                if (lblLoading.InvokeRequired)
                {
                    if (count == 0)
                    {
                        lblLoading.Invoke(new Action(() => lblLoading.Text = "Loading."));
                        count++;
                    }
                    else if (count == 1)
                    {
                        lblLoading.Invoke(new Action(() => lblLoading.Text = "Loading.."));
                        count++;
                    }
                    else if (count == 2)
                    {
                        lblLoading.Invoke(new Action(() => lblLoading.Text = "Loading..."));
                        count++;
                    }
                    else
                    {
                        lblLoading.Invoke(new Action(() => lblLoading.Text = "Loading"));
                        count = 0;
                    }
                }
                else
                {
                    if (count == 0)
                    {
                        lblLoading.Text = "Loading.";
                        count++;
                    }
                    else if (count == 1)
                    {
                        lblLoading.Text = "Loading..";
                        count++;
                    }
                    else if (count == 2)
                    {
                        lblLoading.Text = "Loading...";
                        count++;
                    }
                    else
                    {
                        lblLoading.Text = "Loading";
                        count = 0;
                    }
                }
            }
        }

即使在更新标签之前,启动屏幕也会在错误检查之前关闭。
谢谢nozzy

icnyk63a

icnyk63a1#

在Winform代码中使用backgroundWorker将类似于:
打开按钮单击:

//SHOW YOUR SCREEN
backgrounWorker.Runasync();

 private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
// here you can call :
       backgroundWorker1_ProgressChanged(0,"abc");
       backgroundWorker1_ProgressChanged(2,"abc");
}
    private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {// show your progress here
    if(e.progresspercentage==0){
            listBox3.Items.Insert(0, e.UserState.ToString());
            listBox3.Update();}  
        }

   private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
         //remove splash screen here
        }
wqnecbli

wqnecbli2#

下面是@Sir Rufo提到的IProgress的基本示例。

使用.NET Core 7编码没有异常处理,你需要添加它,尤其是在处理文件时。
执行工作的模型,在本例中是任务。延迟将被你的工作所取代。

public class Operations
{
    public static async Task PerformWork(IProgress<int> progress, CancellationToken cancellationToken)
    {

        for (int index = 0; index <= 100; index++)
        {
            // Simulate an async call that takes some time to complete
            await Task.Delay(100, cancellationToken);

            if (cancellationToken.IsCancellationRequested)
            {
                cancellationToken.ThrowIfCancellationRequested();
            }

            progress?.Report(index);
        }
    }
}

MainForm在Showed事件中显示一个辅助窗体,您可以随时更改为Load事件。

public partial class MainForm : Form
{
    public MainForm()
    {
        InitializeComponent();
        Shown += MainForm_Shown;
    }

    private void MainForm_Shown(object sender, EventArgs e)
    {
        SplashForm splashForm = new();
        try
        {
            if (splashForm.ShowDialog() == DialogResult.OK)
            {
                // work completed
            }
            else
            {
                // user cancelled
            }

        }
        finally
        {
            splashForm.Dispose();
        }
    }
}

Splash表单,注意ReportProgress更新进度条,也可以是标签。此外,有一个取消按钮,如果你可能不想要。

public partial class SplashForm : Form
{
    private readonly CancellationTokenSource 
        _cancellationTokenSource = new();
    public SplashForm()
    {
        InitializeComponent();

        Shown += SplashForm_Shown;
    }

    private async void SplashForm_Shown(object sender, EventArgs e)
    {

        var cancelled = false;
        var progressIndicator = new Progress<int>(ReportProgress);

        try
        {
            await Operations.PerformWork(
                progressIndicator, 
                _cancellationTokenSource.Token);

            // indicates success to main form and closes this form
            DialogResult = DialogResult.OK;
        }
        catch (OperationCanceledException ex)
        {
            cancelled = true;
        }

        if (cancelled)
        {
            MessageBox.Show("Cancelled");
            // indicates user cancelled to main form and closes this form
            DialogResult = DialogResult.Cancel;
        }
    }
    /// <summary>
    /// Update progress bar from Operations.
    /// </summary>
    /// <param name="value"></param>
    private void ReportProgress(int value)
    {
        progressBar1.Increment(1);
    }
    private void CancelOperationButton_Click(object sender, EventArgs e)
    {
        _cancellationTokenSource.Cancel();
    }
}

相关问题