使用线程中的数据更新标签

时间:2018-06-11 09:56:16

标签: c# winforms thread-safety

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

以下是ProcessingUI

形式的Back代码
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();
    public void UpdateStatus()
    {
       lblCounter.Invoke((Action)delegate
        {

            lblCounter.Text += new EventHandler(_processing.Raise);
        });
    }
}

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

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

        }

         public string get(string msg)
                 {
                 return msg;
               } 
          public void Raise(object sender, EventArgs e)
              {
                 get("hello");

                 }

    }

1 个答案:

答案 0 :(得分:0)

使用Progress来处理跨线程访问

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;    
    }
}