回调和onthreadfinish

时间:2013-01-19 16:35:06

标签: c# winforms multithreading delegates

我只是要求最简洁的方法是在线程运行时使用回调来更新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";
        } 
    }

1 个答案:

答案 0 :(得分: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();
    }
}