0

我只是要求最干净的方法来在线程运行时进行回调以更新 GUI,以及在线程完成时调用的方法。

所以在我的示例中,我有一个Counter类(这是任务)和 2 个委托,1 个用于回调,1 个用于完成线程。

这一切都很好,但我觉得这不是最好/最干净/..的方式。

任何建议将不胜感激,我很难理解委托和线程线程的概念,因为我很久以前还没有开始编程。

计数器类

class Counter
{
    private PrintCallback cb;
    private OnActionFinish oaf;

    public void SetCallback(PrintCallback c)
    {
        this.cb = c;
    }

    public void SetOnFinished(OnActionFinish f)
    {
        this.oaf = f;
    }

    public void Count()
    {
        for (int i = 0; i < 1000; i++)
        {
            cb(i);
        }
        oaf();
    }

}

我的主要形式

public delegate void PrintCallback(int i);
public delegate void OnActionFinish();

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        PrintCallback cb = new PrintCallback(Print);
        OnActionFinish otf = new OnActionFinish(Finished);
        Counter c = new Counter();
        c.SetCallback(cb);
        c.SetOnFinished(otf);
        Thread t = new Thread(c.Count);
        t.Start();
        label1.Text = "Thread started";
    }

    private void Print(int i)
    {
        if (textBox1.InvokeRequired)
        {
            textBox1.Invoke((MethodInvoker)delegate { 
                textBox1.Text += i + "\r\n";
            });
        }
        else
        {
            textBox1.Text += i + "\n";
        }
    }

    private void Finished()
    {
        if (label1.InvokeRequired)
        {
            label1.Invoke((MethodInvoker)delegate { 
                label1.Text = "Thread finished";
                textBox1.SelectionStart = textBox1.Text.Length;
                textBox1.ScrollToCaret();
            });
        }
        else
        {
            label1.Text = "Thread finished";
        } 
    }
4

1 回答 1

1

重构你的代码,使用你自己的技术,它可能变成这样:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        label1.Text = "Thread started";
        Counter c = new Counter(Print, Finished);
        new Thread(new ThreadStart(c.Count)).Start();
    }

    private void Print(int i)
    {
        if (InvokeRequired)
            Invoke(new Action<int>(Print), i);
        else
            textBox1.Text += i + "\r\n";
    }

    private void Finished()
    {
        if (InvokeRequired)
        {
            Invoke(new Action(Finished));
        }
        else
        {
            label1.Text = "Thread finished";
            textBox1.SelectionStart = textBox1.Text.Length;
            textBox1.ScrollToCaret();
        }
    }
}


class Counter
{
    private readonly Action<int> _output;
    private readonly Action _finished;

    public Counter(Action<int> output, Action finished)
    {
        _output = output;
        _finished = finished;
    }

    public void Count()
    {
        for (int i = 0; i < 1000; i++)
            _output(i);
        _finished();
    }
}
于 2013-05-02T17:27:15.630 回答