2012-01-24 71 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等)都不使用单独的线程进行排序。

然而,在一个单独的线程上可能会发生什么事件通知。如果你在一个线程上修改列表并在另一个线程上排序,你会得到意想不到的结果。

相关问题