Интерфейс IComparer работает в отдельном потоке в C #? - PullRequest
0 голосов
/ 25 января 2012

Я использую универсальный сортировщик 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;
        }
    }

}

} ​​

РЕДАКТИРОВАТЬ:

Я использую только 1 поток (который я знаю / о создании) в обновлениях и сортировке

Ответы [ 3 ]

1 голос
/ 25 января 2012

РЕДАКТИРОВАТЬ: В статье, которую вы упомянули, они имеют строку:

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 (и все остальное, что касается связанного списка) в поток пользовательского интерфейса. Вы не можете безопасно обновить их из фонового потока по тем же причинам, по которым вы не можете касаться элементов управления пользовательского интерфейса из фонового потока. Но нет, компаратор не работает в своем собственном потоке.
0 голосов
/ 25 января 2012

Нет - это не в отдельном потоке.Интерфейс фактически не представляет исполняемый код - это всего лишь контракт между классами.Итак, вопрос в том, как вы вызываете запрос сортировки и в какой реализации коллекции.Ни один из встроенных классов коллекции (List <>, ArrayList и т. Д.) Не использует отдельный поток для сортировки.

Что может быть в отдельном потоке, однако это уведомления о ваших событиях.Если вы изменяете список в одном потоке и сортируете его в другом, вы получите неожиданные результаты.

0 голосов
/ 25 января 2012

Нет, это не безопасно использовать из нескольких потоков.Сам экземпляр ListViewItem не является неисправным из нескольких потоков, поэтому его использование в IComparer также небезопасно.

...