假设UI更新需要相当长的时间。例如,此虚拟标签需要1秒钟才能更改文本。
public class MyLabel : Label
{
public override string Text
{
get { return base.Text; }
set
{
Debug.WriteLine("Setting " + value);
Thread.Sleep(1000);
base.Text = value;
}
}
}
如果有多个任务想要更新它,那么这些帖子似乎已排队。
var UIContext = SynchronizationContext.Current;
for (int i = 0; i < 10; i++)
{
Task.Factory.StartNew((id) =>
{
Debug.WriteLine(id);
Thread.Sleep((int)id*100);
UIContext.Post((label) =>
{
myLabel1.Text = label.ToString();
}, id);
}, i);
}
标签似乎收到帖子排队,标签最终收到它们,但在这个例子中,下一个会覆盖前一个,所以不需要处理前一个。理想情况下,我想忽略除最后一个之外的所有帖子。我可以看到排队的项目并将其删除吗?
答案 0 :(得分:0)
我想我想错了方向。我没有处理SynchronizationContext
队列,而是创建了自己的队列,它似乎按照我的预期工作。
public class MyLabel : Label
{
SynchronizationContext UIContext;
List<string> TextQueue;
public MyLabel()
{
UIContext = SynchronizationContext.Current;
TextQueue = new List<string>();
}
public override string Text
{
get { return base.Text; }
set
{
Debug.WriteLine("Setting " + value);
Thread.Sleep(1000);
base.Text = value;
}
}
public void QueueTextChange(string text)
{
Debug.WriteLine("Request: " + text);
lock (TextQueue)
{
TextQueue.Add(text);
}
UIContext.Post((x) => { SetTextFromQueue();}, null);
}
void SetTextFromQueue()
{
string last=null;
lock (TextQueue)
{
if (TextQueue.Count > 0)
{
last = TextQueue.Last();
TextQueue.Clear();
}
}
if (last != null)
Text = last;
}
}
其他线程不直接调用myLabel1.Text = ""
,而是调用特殊的排队方法,如下所示。
myLabel1.QueueTextChange(label.ToString());