おそらく、この回答の前に次のステートメントを付ける必要があります。
DependencyProperty
「のシーケンスを配置/順序付けしてに加えられた変更を順序付ける必要がある場合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 に変更