IComparer接口在C#中的一个单独线程上工作吗

本文关键字:单独 一个 线程 工作 接口 IComparer | 更新日期: 2023-09-27 18:21:14

我正在使用一个通用的ListView分类器来实现IComparer接口。

这是在一个独立于主线程的线程上工作吗?

我有一些奇怪的结果。然而,它对静态ListView进行排序很好,一旦它被流数据填充(它订阅了一些不断向其中添加项目的事件),比较就会失败,变得很奇怪。

如果它在一个单独的线程上——我应该如何修改它,这样它就不会干扰填充结果(反之亦然),有什么想法吗?

或者,如果是在同一条线上,有什么想法可以解释为什么会发生这种情况?

下面是更新listView(lstTrades)的更新方法的代码

编辑:我原来粘贴错代码了!!

  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;
        }
    }
}

}

编辑:

我在更新和排序时只使用了一个线程(我知道/正在创建)

IComparer接口在C#中的一个单独线程上工作吗

编辑:在你提到的文章中,他们有一行:

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控件的原因相同。但不,比较器不是在它自己的线程上运行的。

不,从多个线程使用这是不安全的。ListViewItem实例本身在多个线程中不是不可用的,因此它在IComparer中的使用也是不安全的。

否-它不在单独的线程上。接口实际上并不代表任何可执行代码,只是类之间的契约。因此,问题是如何调用排序请求以及在什么集合实现上。任何内置集合类(List<>、ArrayList等)都不使用单独的线程进行排序。

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