2011-11-02 96 views
0

我一直在嘗試學習委託。我只是創建了一個按鈕,標籤和複選框。如果我點擊複選框,時間格式會改變。如果我點擊按鈕,我會相應地打印日期。但是想要使用asynchromous代表即使用另一個線程的時候,我堅持錯誤跨線程操作無效:異步委託錯誤

public delegate void AsyncDelegate(bool seconds); 

public partial class Form1 : Form 
{ 
    AsyncDelegate ad; 
    TimeZ t = new TimeZ(); 
    public Form1() 
    { 
     InitializeComponent(); 
    } 

private void btn_async_Click(object sender, EventArgs e) 
    { 

     ad = new AsyncDelegate(t.GetTime); 
     AsyncCallback acb = new AsyncCallback(CB); 
     if (chk_sec.Checked) 
     { 
      ad.BeginInvoke(true, acb, null); 
     } 
     else 
      ad.BeginInvoke(false, acb, null); 


    } 
    public void CB(IAsyncResult ar) 
    { 
     t.Tim = ar.ToString(); 
     ad.EndInvoke(ar); 
     lbl_time.Text = t.Tim; 
    } 

而在另一個類庫我得到上面使用Timez。我在項目

public class TimeZ 
{ 
    private string tim; 
    public string Tim 
    { 
     get 
     { 
      return tim; 
     } 
     set 
     { 
      tim = value; 
     } 
    } 
    public string GetTime(bool seconds) 
    { 
     if (seconds) 
     { 
      return DateTime.Now.ToLongTimeString(); 
     } 
     else 
      return DateTime.Now.ToShortTimeString(); 
    } 
} 

添加位置的參考然而,當我運行程序我得到這個錯誤:

Cross-thread operation not valid: Control 'lbl_time' accessed from a thread other than 
    the thread it was created on. 

u能幫助我如何解決這個問題?

+0

令我難以置信的是,有人會對此讚不絕口。你甚至試圖用這個代碼做什麼? –

回答

4

您無法從不是表單線程的線程訪問窗體並控制屬性和方法。

在windows中,每個窗口都綁定到創建它的線程。

你只能用Control.BeginInvoke或更有用的System.Threading.SynchronizationContext類來做到這一點。

http://msdn.microsoft.com/it-it/library/system.threading.synchronizationcontext(v=vs.95).aspx

http://msdn.microsoft.com/it-it/library/0b1bf3y3(v=vs.80).aspx

這意味着,你必須通過同步上下文張貼例如在形式上線程異步的另一代表。

public partial class Form1 : Form 
{ 
    AsyncDelegate ad; 
    TimeZ t = new TimeZ(); 

    // Our synchronization context 
    SynchronizationContext syncContext; 

    public Form1() 
    { 
     InitializeComponent(); 

     // Initialize the synchronization context field 
     syncContext = SynchronizationContext.Current; 
    } 

    private void btn_async_Click(object sender, EventArgs e) 
    { 

     ad = new AsyncDelegate(t.GetTime); 
     AsyncCallback acb = new AsyncCallback(CB); 
     if (chk_sec.Checked) 
     { 
      ad.BeginInvoke(true, acb, null); 
     } 
     else 
     { 
      ad.BeginInvoke(false, acb, null); 
     } 
    } 

    public void CB(IAsyncResult ar) 
    { 
     // this will be executed in another thread 
     t.Tim = ar.ToString(); // ar.ToString()???? this will not give you the time for sure! why? 
     ad.EndInvoke(ar); 

     syncContext.Post(delegate(object state) 
     { 
      // This will be executed again in form thread 
      lbl_time.Text = t.Tim; 
     }, null); 
    } 

我不知道爲什麼你需要異步回調但打印時間:)真的不知道爲什麼,以爲它只是一些測試代碼。

+0

嗨salvatore,請你幫我解決上述問題。 – user838359

+0

剛剛編輯添加一些代碼,試試吧。 –

+0

我不知道我要去哪裏但是現在它打印出System.Remote.Remoting.Messaging.AsyncResult而不是當前日期 – user838359