2013-10-05 87 views
1

我有一個文本框的WinForm和上框TextChanged執行後臺線程:螺紋內螺紋試圖調用和更新UI

private void txtFathersLast_TextChanged(object sender, EventArgs e) 
{ 
ThreadPool.QueueUserWorkItem(_ => WaitWhileUserTyping()); 
} 
private void WaitWhileUserTyping() 
     { 
      var keepWaiting = true; 

      while (keepWaiting) 
      { 
       _keyPressed = false; 

       Thread.Sleep(TypingDelay); 

       keepWaiting = _keyPressed; 
      } 

      Invoke((MethodInvoker)(ExecuteSearch)); 

      _waiting = false; 
     } 


private void ExecuteSearch() 
     { 
      Thread.Sleep(200); 

      Task.Factory.StartNew(() => 
      { 

       using (DataReference.SearchWCF search = new DataReference.SearchWCF()) 
       { 
        _similaritySearchResults = search.SearchPersonBySimilarity(txtFathersLast.Text, txtMothersLast.Text, txtName.Text, DateTime.Now, 10); 
       } 

      }).ContinueWith(t=>{ 

       if (this.InvokeRequired) 
       { 
        this.BeginInvoke(new Action(() => 
        { 
         if (_similaritySearchResults != null && _similaritySearchResults.Tables["data"].Rows.Count > 0) 
         { 
          DataTable dt = _similaritySearchResults.Tables["data"]; 

          Infragistics.Win.Misc.UltraTile newTile = null; 

          for (int index = 0; index < dt.Rows.Count; index++) 
          { 
           newTile = new Infragistics.Win.Misc.UltraTile("Person X"); 
           newTile.Control = new CustomControls.Controls.PersonResult("123", "123", index + 150); 
           newTile.Tag = new Guid("90D27721-7315-4B86-9CFD-4F7D02921E9A"); 
           newTile.DoubleClick += TileDoubleClick; 
           tilePanel.Tiles.Add(newTile); 
          } 
         } 

        })); 
       } 
       else 
       { 
        if (_similaritySearchResults != null && _similaritySearchResults.Tables["data"].Rows.Count > 0) 
        { 
         DataTable dt = _similaritySearchResults.Tables["data"]; 

         Infragistics.Win.Misc.UltraTile newTile = null; 

         for (int index = 0; index < dt.Rows.Count; index++) 
         { 
          newTile = new Infragistics.Win.Misc.UltraTile("Person X"); 
          newTile.Control = new CustomControls.Controls.PersonResult("123", "123", index + 150); 
          newTile.Tag = new Guid("90D27721-7315-4B86-9CFD-4F7D02921E9A"); 
          newTile.DoubleClick += TileDoubleClick; 
          tilePanel.Tiles.Add(newTile); 
         } 
        } 
       } 




      }, TaskScheduler.FromCurrentSynchronizationContext()); 


     } 

這是工作的罰款,該應用程序進入到一個數據庫,然後得到的結果和更新UI,根據數據庫返回的記錄數量向控件添加切片。現在

,問題是當我嘗試添加另一個後臺線程到我的自定義控制:

新CustomControls.Controls.PersonResult( 「123」, 「123」,指數+ 150);

該控件的代碼是:

protected override void InitLayout() 
     { 
      // if I comment this then everything works fine 
      // but if I leave this, then the UI freezes!! 
      GetPictureAsync(); 

      base.InitLayout(); 
     } 

/// <summary> 
     /// 
     /// </summary> 
     private void GetPictureAsync() 
     { 
      // This line needs to happen on the UI thread... 
      TaskScheduler uiScheduler = TaskScheduler.FromCurrentSynchronizationContext(); 


      Task.Factory.StartNew(() => 
      { 
       Random sleep = new Random(); 
       System.Threading.Thread.Sleep(sleep.Next(1000,3000)); 
       if (this.pbPhoto.InvokeRequired) 
       { 
        this.pbPhoto.Invoke(new Action(() => 
        { 
         this.Load(@"E:\Photos\" + PhotoId.ToString() + ".jpg"); 
         //this.pbPhoto.Image = Utility.Common.GetResourceImage("woman_sample.jpg"); 
        })); 
       } 
       else 
       { 
        this.Load(@"E:\Photos\" + PhotoId.ToString() + ".jpg"); 
        //this.pbPhoto.Image = Utility.Common.GetResourceImage("woman_sample.jpg"); 
       } 


      }, CancellationToken.None, TaskCreationOptions.None, uiScheduler); 
     } 

所以,問題似乎是我第一次執行一個線程看時開始搜索,然後該線程裏面我爲了得到數據運行另一個線程從數據庫中,然後在UI中更新的每個控件將運行另一個線程來獲取圖片並更新一個picturebox。

任何人都知道如何解決這個問題?或者解決這個問題的方法?

回答

0

當你調用

new CustomControls.Controls.PersonResult("123", "123", index + 150) 

爲 「123」 文字字符串,或者他們正在從UI控件讀取。例如,

new CustomControls.Controls.PersonResult(txtFathersName.Text", txtMothersName.Text, index + 150) 

我現在不能測試它,但是不訪問Text屬性不允許從創建控件的線程以外的線程?

0

我認爲問題在於你強制任務GetPictureAsync在UI線程上執行,然後你打電話Thread.Sleep()。這個update UI in Task using TaskScheduler.FromCurrentSynchronizationContext問題解決了你遇到的同樣的問題。我會重寫你的代碼爲:

private void async GetPictureAsync() 
{ 
    Random sleep = new Random(); 
    await TaskEx.Delay(sleep.Next(1000,3000)); 
    this.Load(@"E:\Photos\" + PhotoId.ToString() + ".jpg"); 
}