2013-03-26 57 views
1

使用Visual Studio 2012 ulti,C#.NET WPF。關於textchanged事件的WPF線程和任務

在我的代碼中使用任務過去很簡單。

我所要做的就是創建一個委託,爲我的代碼創建一個函數,創建一個任務,事件將是一個簡單的按鈕。簡單的東西。我的問題是有以下...

  • 創建一個線程爲每個平常不過事件將在文本改變

問題IM有在思考的邏輯,如果我只是改變事件中,我看不到這個工作因爲用戶可以鍵入速度比該代碼可以運行(在這種情況下,一個SQL查詢的SELECT語句)。因爲它會嘗試運行許多我認爲不可行的任務。

基本上用戶輸入用於按名稱或編號搜索帳戶的文本框。 在這個文本框中,我想要對整個過程進行線程化。

我能想到的唯一的解決辦法是作爲文本改變如果存在線程仍在運行,停止該線程創建新的,但不知道如果多數民衆贊成在做它作爲一個乾淨的方式它的SQL存儲過程不適合調用。

因此,任何機構都得到了解決辦法?

如果您需要更多信息,請查詢。生病還提供了目前工作,在需要給你一個瞭解一些代碼...

設置Invoke方法了:在另一種方法

private void SetDataGrid(bool AutoGenerateColumns, Object DataSource, String DataMember, DataGridViewAutoSizeColumnsMode Mode) 
    { 
     if (this.ParetoGrid.InvokeRequired) 
     { 
      this.ParetoGrid.Invoke(new Action<bool, Object, String, DataGridViewAutoSizeColumnsMode>(SetDataGrid), 
             AutoGenerateColumns, DataSource, DataMember, Mode); 
     } 
     else 
     { 
      this.ParetoGrid.AutoGenerateColumns = AutoGenerateColumns; 
      this.ParetoGrid.DataSource = DataSource; 
      this.ParetoGrid.DataMember = DataMember; 
      ParetoGrid.AutoResizeColumns(Mode); 
     } 
    } 

呼叫invoke方法:

Private void GetSomething() 
{ 
    //sql code get data 
    SetDataGrid(true, dataSet1, "Pareto", DataGridViewAutoSizeColumnsMode.AllCells); 
} 

然後在事件上簡單地開始任務:

private void myButton_Click(Object sender, EventArgs e) 
{ 
    Task t = new Task(() => getSomething()); 
    t.Start(); 
} 

正如你所看到的簡單的東西,但簡單的改變事件似乎把整個邏輯搞亂了。

+1

'我在winforms上的代碼曾經很簡單。' - 不正確。 winforms不允許將用戶界面和應用程序邏輯/數據進行清晰而真實的分離,從而迫使你陷入幾乎任何事情的可怕黑客行列。 WPF + MVVM乾淨,漂亮,可擴展。無可否認,非MVVM WPF可能會很痛苦,但爲什麼要這樣做呢? – 2013-03-26 14:08:08

+0

以及這是我的第一個應用程序使用WPF,只是徘徊,如果我可以使用舊的勝利形式代碼修改略有wpf。 – lemunk 2013-03-26 14:13:21

+1

不是真的。你可以做到這一點,但WPF如果使用MVVM模式則更加美觀和愉快,而不是來自Winforms無法分離UI和邏輯的可怕黑客。 – 2013-03-26 14:14:38

回答

0

我建議將這個邏輯從任務移動到Timer回調,然後讓你的OnTextChanged處理程序在每次觸發時重置計時器(當然,只有定時器觸發一次)。通過在.5-1秒之後使計時器消逝,或者類似的事情,你可以等到所有的文本輸入完成後再實際調用你的邏輯。但用戶的體驗仍然相當敏感。

例子:

private System.Threading.Timer keyEntryTimer = new Timer(Logic,null,-1,-1); 

public void HandleEvent(objet sender, EventArgs args) 
{ 
    keyEntryTimer.Change(500,-1); 
} 

public void Logic(objet state) 
{ 
    //Your task logic would go here to read from the text etc... 
    //You'll have to handle any UI updates either by firing off a task once the DB results return or using a dispatcher 
} 
+0

我的一個夥伴剛剛提出了類似的事情,但對定時器不確定,我一直認爲線程和定時器非常難以一起使用,但我想它是如何在邏輯中實現這兩者的。你能否提供一個你的意思的例子,所以我可以開始玩測試? – lemunk 2013-03-26 14:16:02

0

您可以簡單地緩存所有帳戶,當他們進入這種搜索模式。然後,當他們在文本框中輸入文本時,您可以搜索緩存帳戶。在每個按鍵的不同線程中執行查詢對應用程序來說非常沉重。

0

我可能會做其他的參考答案的組合,並儘量拖延使用計時器或一些類似的方法將SQL語句的射擊,但如果用戶延遲足夠長的時間要觸發的SQL然後嘗試僅過濾從該點向前返回的結果(僅當搜索字符串明顯變得更加嚴格時)。這可以爲您節省昂貴的SQL往返次數,並在第一次命中後爲您提供工作緩存(與嘗試緩存所有內容相比,該緩存應該更小)。

希望這會有所幫助。