我可能应该用这个陈述来作为这个答案的开头:
“如果您需要DependencyProperty
通过排列/排序 的顺序来对 a 所做的更改进行排序DependencyPropertyChangedCallbacks
,那么您可能做错了。”
也就是说,这里有一些闲置的代码,有点像你在说的那样:
物体:
public class SomeThing : DependencyObject, IDisposable
{
public static readonly DependencyProperty StatusProperty =
DependencyProperty.Register(
"Status",
typeof(string),
typeof(SomeThing),
new FrameworkPropertyMetadata(OnStatusChanged));
public static readonly DependencyProperty DataProperty =
DependencyProperty.Register(
"Data",
typeof(string),
typeof(SomeThing),
new FrameworkPropertyMetadata(OnDataChanged));
// The OrderedBag is from the Wintellect.PowerCollections,
// as I was too lazy to write my own PriorityQueue-like implementation
private static OrderedBag<Tuple<int, DependencyObject, DependencyPropertyChangedEventArgs>> _changeQueue =
new OrderedBag<Tuple<int, DependencyObject, DependencyPropertyChangedEventArgs>>((l,r) => l.Item1.CompareTo(r.Item1));
private static object _syncRoot = new object();
private static Task queueTenderTask;
private static CancellationTokenSource canceller;
static SomeThing()
{
canceller = new CancellationTokenSource();
queueTenderTask = Task.Factory.StartNew(queueTender);
}
public string Status
{
get { return (string)this.GetValue(StatusProperty); }
set { this.SetValue(StatusProperty, value); }
}
public string Data
{
get { return (string)this.GetValue(DataProperty); }
set { this.SetValue(DataProperty, value); }
}
public void Dispose()
{
if(canceller != null)
{
canceller.Cancel();
if(queueTenderTask != null)
{
queueTenderTask.Wait();
}
}
}
private static void OnStatusChanged(
DependencyObject dobj,
DependencyPropertyChangedEventArgs args)
{
lock(_syncRoot)
{
_changeQueue.Add(Tuple.Create(0, dobj, args));
}
}
private static void OnDataChanged(
DependencyObject dobj,
DependencyPropertyChangedEventArgs args)
{
lock(_syncRoot)
{
_changeQueue.Add(Tuple.Create(1, dobj, args));
}
}
private static void ProcessChange(
Tuple<int, DependencyObject,DependencyPropertyChangedEventArgs> pair)
{
// do something useful?
Console.WriteLine(
"Processing change on {0} from {1} to {2}",
pair.Item3.Property.Name,
pair.Item3.OldValue,
pair.Item3.NewValue);
}
private static void queueTender()
{
Console.WriteLine("Starting queue tender...");
var shouldCancel = canceller.IsCancellationRequested;
while(!shouldCancel)
{
lock(_syncRoot)
{
if(_changeQueue.Count > 0)
{
var nextUp = _changeQueue[0];
_changeQueue.RemoveFirst();
ProcessChange(nextUp);
}
}
for(int i=0;i<10;i++)
{
shouldCancel = canceller.IsCancellationRequested;
if(shouldCancel) break;
Thread.Sleep(10);
}
}
}
}
和测试:
void Main()
{
var rnd = new Random();
using(var ob = new SomeThing())
{
for(int i=0;i<10;i++)
{
if(rnd.NextDouble() > 0.5)
{
Console.WriteLine("Changing Status...");
ob.Status = rnd.Next(0, 100).ToString();
}
else
{
Console.WriteLine("Changing Data...");
ob.Data = rnd.Next(0, 100).ToString();
}
}
Console.ReadLine();
}
}
输出:
开始排队招标...
更改状态...
更改状态...
更改状态...
更改数据...
更改数据...
更改数据...
更改数据...
更改数据...
更改数据...
更改状态...
处理状态从到 1 的更改
处理状态从 1 到 73 的更改
处理状态从 73 到 57 的更改
处理状态从 57 到 33 的更改
处理从数据到 10 的更改
处理数据从 10 到 67 的变化
处理数据从 67 到 40 的变化
处理数据从 40 到 64 的变化
处理数据从 64 到 47 的变化
处理数据从 47 到 81 的变化