2012-01-24 49 views
0

我正在使用實現IComparer接口的通用ListView分揀機。IComparer接口是否在C#中的單獨線程上工作?

這工作在一個單獨的線程從主線程?

我有一些時髦的結果。它對靜態ListView進行排序很好,但是,一旦它被填充流數據(它訂閱了一些不斷向其添加項目的事件),比較失敗並且變得怪異。

如果它在一個單獨的線程上 - 關於如何修改它的任何想法,以便它不會影響填充結果(反之亦然)?

或者如果它是在相同的線程上,爲什麼會發生這種情況的任何想法?

下面是更新的ListView(lstTrades

EDIT用於更新方法的代碼:我粘貼錯碼本來!!

private void UpdateList(foo t) 
       { 
       lstTrades.Items.Add(t.a); 
       int i = lstTrades.Items.Count - 1; 
       lstTrades.Items[i].SubItems.Add(t.b); 
       lstTrades.Items[i].SubItems.Add(t.c.ToString()); 
       lstTrades.Items[i].SubItems.Add(t.d.ToString()); 
       lstTrades.Items[i].SubItems.Add(Math.Round(e.pnl, 2).ToString()); 
       lstTrades.Items[i].SubItems.Add(t.f.ToString()); 
       lstTrades.Items[i].SubItems.Add(t.g.ToShortTimeString()); 
       lstTrades.Items[i].SubItems.Add(t.h); 
       lstTrades.Items[i].SubItems.Add(t.i.ToString()); 
       } 

排序的代碼是從http://support.microsoft.com/kb/319401

using System.Collections; 
using System.Windows.Forms; 
using System; 


namespace Aladmin2 
{ 


/// <summary> 
/// This class is an implementation of the 'IComparer' interface. 
/// </summary> 
public class ListViewColumnSorter : IComparer 
{ 
    /// <summary> 
    /// Specifies the column to be sorted 
    /// </summary> 
    private int ColumnToSort; 
    /// <summary> 
    /// Specifies the order in which to sort (i.e. 'Ascending'). 
    /// </summary> 
    private SortOrder OrderOfSort; 
    /// <summary> 
    /// Case insensitive comparer object 
    /// </summary> 
    private CaseInsensitiveComparer ObjectCompare; 

    /// <summary> 
    /// Class constructor. Initializes various elements 
    /// </summary> 
    public ListViewColumnSorter() 
    { 
     // Initialize the column to '0' 
     ColumnToSort = 0; 

     // Initialize the sort order to 'none' 
     OrderOfSort = SortOrder.None; 

     // Initialize the CaseInsensitiveComparer object 
     ObjectCompare = new CaseInsensitiveComparer(); 
    } 

    /// <summary> 
    /// This method is inherited from the IComparer interface. It compares the two objects passed using a case insensitive comparison. 
    /// </summary> 
    /// <param name="x">First object to be compared</param> 
    /// <param name="y">Second object to be compared</param> 
    /// <returns>The result of the comparison. "0" if equal, negative if 'x' is less than 'y' and positive if 'x' is greater than 'y'</returns> 
    public int Compare(object x, object y) 
    { 
     int compareResult; 
     ListViewItem listviewX, listviewY; 

     // Cast the objects to be compared to ListViewItem objects 
     listviewX = (ListViewItem)x; 
     listviewY = (ListViewItem)y; 

     // Compare the two items 
     DateTime dateValue; 
     if (DateTime.TryParse(listviewX.SubItems[ColumnToSort].Text, out dateValue)) 
     { 

      compareResult = DateTime.Compare(DateTime.Parse(listviewX.SubItems[ColumnToSort].Text), DateTime.Parse(listviewY.SubItems[ColumnToSort].Text)); 

     } 
     else 
     { 

      compareResult = ObjectCompare.Compare(listviewX.SubItems[ColumnToSort].Text, listviewY.SubItems[ColumnToSort].Text); 
     } 

     // Calculate correct return value based on object comparison 
     if (OrderOfSort == SortOrder.Ascending) 
     { 
      // Ascending sort is selected, return normal result of compare operation 
      return compareResult; 
     } 
     else if (OrderOfSort == SortOrder.Descending) 
     { 
      // Descending sort is selected, return negative result of compare operation 
      return (-compareResult); 
     } 
     else 
     { 
      // Return '0' to indicate they are equal 
      return 0; 
     } 
    } 

    /// <summary> 
    /// Gets or sets the number of the column to which to apply the sorting operation (Defaults to '0'). 
    /// </summary> 
    public int SortColumn 
    { 
     set 
     { 
      ColumnToSort = value; 
     } 
     get 
     { 
      return ColumnToSort; 
     } 
    } 

    /// <summary> 
    /// Gets or sets the order of sorting to apply (for example, 'Ascending' or 'Descending'). 
    /// </summary> 
    public SortOrder Order 
    { 
     set 
     { 
      OrderOfSort = value; 
     } 
     get 
     { 
      return OrderOfSort; 
     } 
    } 

} 

輕輕修改後的代碼}

編輯:

我只使用1個線程(我知道/創建)的這兩個更新和排序

+1

我不認爲這是一個線程問題 - 這只是一個紅鯡魚(在這種情況下)。添加新結果後,您不需要重新排序。 –

+0

請注意,我最初發布了錯誤的更新代碼,其中一個是生成可正常工作的靜態列表的catchup代碼。尊敬的新代碼 – Sam

+0

@Chris Shain--並不打算讓它成爲紅鯡魚。只是抓我的頭,看看爲什麼發生這種情況 – Sam

回答

1

編輯:在你提到的文章,它們有線:

this.listView1.Sort();

嘗試添加以下內容到ProcessUpdate方法,就在年底。

此排序器不實現連續排序 - 您需要在添加和刪除數據時繼續調用該排序器。對不起,我們都向你介紹了線程。

編輯#2:另外,嘗試一下本作的ProcessUpdate方法:

private void UpdateList(foo t) 
{ 
    // Create the item 
    ListViewItem li = new ListViewItem(t.a); 

    // Add all of the subitems 
    li.SubItems.Add(t.b); 
    li.SubItems.Add(t.c.ToString()); 
    li.SubItems.Add(t.d.ToString()); 
    li.SubItems.Add(Math.Round(e.pnl, 2).ToString()); 
    li.SubItems.Add(t.f.ToString()); 
    li.SubItems.Add(t.g.ToShortTimeString()); 
    li.SubItems.Add(t.h); 
    li.SubItems.Add(t.i.ToString()); 

    // Add the item to the list 
    lstTrades.Items.Add(li); 

    // Sort the list 
    lstTrades.Sort(); 
} 
如果你沒有準備好,你需要元帥`ProcessUpdate`方法(和其他任何觸動綁定列表)到UI線程。您無法從後臺線程安全地更新這些內容,原因與您無法從後臺線程觸摸UI控件的原因相同。 但是不,比較器沒有運行在它自己的線程上。
+0

嘗試過 - 同樣的問題。發生什麼事是,當我點擊排序和新項目進來 - 我得到了一大堆空白的子項目。看起來子項目是問題。 – Sam

+0

這是因爲你得到ListItem的方式。我會編輯我的答案,以反映正確的方式來做到這一點。 –

+0

現在試試 - 有道理 – Sam

0

沒有這是不安全的,從多個使用廣告。 ListViewItem實例本身並不是從多個線程不可變的,因此在IComparer內使用也是不安全的。

+0

好吧,我只使用1個線程,但問題是,當我實現'Icomparer' - 是否會創建一個新線程?有關如何解決這個問題的任何建議,以便我可以實際執行排序? – Sam

+1

@Sam no。 'IComparer'的實現不會創建一個線程。沒有接口這樣做。 – JaredPar

0

否 - 它不在單獨的線程中。 接口實際上並不代表任何可執行代碼 - 只是類之間的契約。所以問題是你是如何調用排序請求和什麼集合實現。內置的集合類(列表<>,ArrayList等)都不使用單獨的線程進行排序。

然而,在一個單獨的線程上可能會發生什麼事件通知。如果你在一個線程上修改列表並在另一個線程上排序,你會得到意想不到的結果。

相關問題