2013-01-19 27 views
0

我只是要求最簡潔的方式來有一個回調更新圖形用戶界面,當一個線程正在運行和一個方法,將在線程完成後調用。回調和onthreadfinish

所以在我的例子中,我有一個計數器類(這是任務),和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"; 
     } 
    } 
+2

你爲什麼不使用BackgroundWorker類?它做到了這一切。 –

+0

@Hans:我建議你使用'BackgroundWorker'來發布帶有源代碼的解決方案:) –

+0

那麼,我們真的不需要在這裏添加示例編號10,001。 –

回答

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