使用线程中的数据更新标签 [英] Updating label with data from thread

查看:109
本文介绍了使用线程中的数据更新标签的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试更新Windows窗体中的标签。这个动作发生在一个单独的类中,但是动作发生在一个单独的类中。标签应该更新,但事情似乎不起作用。请帮助



以下是处理表格的返回代码



我试过的:



I am trying to update a label in windows forms. The action is happening in a separate class but while the action is happening on a separate class. The label should be updated, but things seem to be not working. Kindly assist

Below is the Back code of the form ProcessingUI

What I have tried:

public partial class ProcessingUI : Form
{
    private void start_Click(object sender, EventArgs e)
    {
        StartProcessingTask();
    }

     private void StartProcessingTask()
    {
        if (_isRunning)
            return;

        _isRunning = true;

        _taskToken = new CancellationTokenSource();

            Task.Factory.StartNew(() =>
            {
                while (_isRunning)
                {

                    var data = _processing.Processdata(lblCounter, _taskToken);
                    if (data.Success)
                        _isRunning = false;
                    if (_taskToken.IsCancellationRequested)
                        return;
                }

            });

    }

    public delegate void SetStatusCallback(string message);
    public void UpdateStatus(string message)
    {
        if (this.lblCounter.InvokeRequired)
        {

            this.Invoke(new SetStatusCallback(UpdateStatus), 
                 message);                                   
        }
        else
            this.lblCounter.Text = message;
    }
}





然后这是一个单独的类,有动作,基本上只是更新。现在在更新时我只想传递正在更新的记录。所以我从表单中调用Method并在此类中使用它。





Then here is a separate class that has the action, basically its just updating. Now on update I just want to pass the record that is being updated. So i call the Method from the form and use it in this class.

public class Processing
   {
        public Results Processdata(CancellationTokenSource taskToken)
       {
       foreach (var record in dataCases)
               {
          //Doing other things here like updating
            new ProcessingUI().UpdateStatus(record.RequestReference);//This is the method I am calling from the form.
           }

       }
   }

推荐答案

new ProcessingUI().UpdateStatus(record.RequestReference);//This is the method I am calling from the form.

你所做的只是创建ProcessingUI表单的多个实例......而不是显示它们。



你需要表格的一个实例,你显示并更新。

All you are doing is creating multiple instances of the "ProcessingUI form" ... and not "showing" them.

You need "one instance" of your form, that you "show" and update.


一个相对简单的解决方案就是使用 进度< T> [ ^ ],它负责管理跨线程访问。

One relatively simple solution would be to use the Progress<T> class[^], which takes care of the cross-thread access for you.
public class Processing
{
    public Results ProcessData(IProgress<string> statusReporter, CancellationToken cancellationToken)
    {
        foreach (var record in dataCases)
        {
            // Doing other things here like updating
            
            // Update the status:
            statusReporter.OnReport(record.RequestReference);
            
            // Stop if the task has been cancelled:
            cancellationToken.ThrowIfCancellationRequested();
        }
    }
}

public partial class ProcessingUI : Form
{
    private void start_Click(object sender, EventArgs e)
    {
        StartProcessingTask();
    }

    private void StartProcessingTask()
    {
        if (_isRunning)
            return;
        
        _isRunning = true;
        _taskToken = new CancellationTokenSource();
        
        CancellationToken cancellationToken = _taskToken.Token;
        IProgress<string> statusReporter = new Progress<string>(UpdateStatus);

        Task.Run(() =>
        {
            while (_isRunning)
            {
                var data = _processing.ProcessData(lblCounter, cancellationToken);
                if (data.Success)
                {
                    _isRunning = false;
                }
                else
                {
                    cancellationToken.ThrowIfCancellationRequested();
                }
            }
        });
    }

    private void UpdateStatus(string message)
    {
        lblCounter.Text = message;    
    }
}


如果你想从不同的线程更新标签状态,我建议使用BackgroundWorker Class(System.ComponentModel) [ ^ ]



详情请见:

初学者的BackgroundWorker类示例 [ ^ ]

演练:与B的多线程ackgroundWorker组件(C#)| Microsoft Docs [ ^ ]

使用后台工作者的多线程,C# [ ^ ]

如何:对Windows窗体控件进行线程安全调用Microsoft Docs [ ^ ]
If you would like to update label status from different thread, i'd suggest to use BackgroundWorker Class (System.ComponentModel)[^]

For further details, please see:
BackgroundWorker Class Sample for Beginners[^]
Walkthrough: Multithreading with the BackgroundWorker Component (C#) | Microsoft Docs[^]
MultiThreading Using a Background Worker, C#[^]
How to: Make Thread-Safe Calls to Windows Forms Controls | Microsoft Docs[^]


这篇关于使用线程中的数据更新标签的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆