我正在使用实现IComparer
接口的通用ListView排序器。
这是否与主线程分开?
我有一些时髦的结果。它对静态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个线程(我知道/创建)
答案 0 :(得分: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控件的原因相同。
但不,比较器没有在它自己的线程上运行。
德尔>
答案 1 :(得分:0)
不能从多个线程使用这是不安全的。 ListViewItem
实例本身并不能从多个线程中找不到,因此它在IComparer
中的使用也是不安全的。
答案 2 :(得分:0)
不 - 它不在一个单独的线程上。 接口实际上并不代表任何可执行代码 - 只是类之间的契约。所以问题是你如何调用排序请求和什么集合实现。内置的集合类(List&lt;&gt;,ArrayList等)都没有使用单独的线程进行排序。
可能在单独的线程上的是您的事件通知。如果您在一个线程上修改列表并在另一个线程上对其进行排序,则会产生意外结果。