2011-12-09 35 views
1

當我在窗體初始化後運行代碼時,它以我想要的方式工作。但是,當我在form Load事件中第一次加載它時,它滯後於繪圖一秒的UI。我不想做一個啓動畫面,因爲已經有一些UI元素表明工作正在進行。線程在窗體加載滯後UI

volatile bool ABfired = false; 
    public form_Main() 
    { 
     InitializeComponent(); 
    } 

    void GetSearchableDataCache() 
    { 
     this.UIThread(() => 
     { 
      ultraActivityIndicator1.AnimationEnabled = true; 
      ultraLabel_Status.Text = "Querying SQL..."; 
     }); 

     var projids = new List<string>(); 
     var names = new List<string>(); 

     ABfired = false; 

     Thread A = (new Thread(() => 
     { 
      while (!ABfired) 
      { 
      } 
      projids = new sql.ProjectIDs(true).Get(); 
     }) 
     { 
      Name = "Thread A", IsBackground = true 
     }); 
     Thread B = (new Thread(() => 
     { 
      while (!ABfired) 
      { 
      } 
      names = new sql.names(true).Get(); 
     }) 
     { 
      Name = "Thread B", IsBackground = true 
     }); 

     Thread AB = (new Thread(() => 
     { 
      ABfired = true; 
      while (A.IsAlive || B.IsAlive) 
      { 
      } 
      this.UIThread(() => 
      { 
       ultraActivityIndicator1.AnimationEnabled = false; 
       ultraLabel_Status.Text = "Ready"; 
      }); 
     }) 
     { 
      Name = "Thread AB", IsBackground = true 
     }); 

     A.Start(); 
     B.Start(); 
     AB.Start(); 
    } 

private void form_Main_Load(object sender, EventArgs e) 
    { 
     GetSearchableDataCache(); 
    } 

回答

3

你的線程是,所以它們都使用了一個完整的CPU內核。
這會顯着降低系統速度。

你應該永遠不要等到現在使用while循環。
取而代之,請等待ManualResetEvent

但是,您可以使用Task s更簡單的實現來替換所有代碼,並且不需要明確的線程。
使用Task.ContinueWith將允許您在完成前一個任務後運行任務而不會浪費線程。

+0

謝謝,這似乎工作。事實證明,我正在使用的控件往往滯後於自己。但我學到了一些有價值的東西。 – Jai

0

啊 - 學習編程。多一點「它有效」。如何 - 這是接近CPU濫用,因爲我曾經見過它的未來。

而(!ABfired)

廢話,尤其是ABFired不鎖,不同步。查找一個MUTEX,或者ManualResetEvent。你正在使用一個cpu核心,甚至不確定你是否有memroy障礙,以便線程看到改變後的值。

其次,你不能從這些線程返回到UI,而沒有像做 - 像調用回主線程那樣。

三,也許形式LAOD不是那麼正確的地方?怎麼激活表單?

四,三隻玩玩搞笑遊戲的線程?不要使用線程來啓動,使用任務和連續數據 - 你會以20年來我看到的最糟糕的形式重建那些東西。 {}

+0

你說得對,我很抱歉。這個項目的很大一部分是搞清楚我在這方面做了什麼。 – Jai