在儿童控制Meathoverride oka uielement上的性能。
有一个功能可以绘制我试图加速的10k不同尺寸的矩形。 将RECT分组分配,每个组可能包含超过1K的RECT。
在MenevoSoverride()和10s+上绘制大约20s+的所有矩形需要30s+。当基本童年(又称一个组)具有数百万个矩形时,需要花费很多时间来做foreach。
public class MyPanel : Panel
{
protected override Size MeasureOverride(Size constraint)
{
Size availableSize = new Size(double.PositiveInfinity, double.PositiveInfinity);
foreach (UIElement element in base.InternalChildren)
{
if (element != null)
{
element.Measure(availableSize);
}
}
return new Size();
}
protected override Size ArrangeOverride(Size finalSize)
{
foreach (UIElement element in base.InternalChildren)
{
if (!element.IsMeasureValid)
continue;
var x = GetX(element);
var y = GetY(element);
var width = element.DesiredSize.Width;
var height = element.DesiredSize.Height;
element.Arrange(new Rect(x - width * 0.5, y - height * 0.5, width, height));
}
return finalSize;
}
}
这个从面板中派生的类具有很多功能,我不能简单地用矩形或边框替换它。因此,我尝试从中做foreach,这样:
protected override Size MeasureOverride(Size constraint)
{
var list = base.InternalChildren.Cast<UIElement>().ToList();
Size availableSize = new Size(double.PositiveInfinity, double.PositiveInfinity);
MeeasureTest(list, constraint);
return new Size();
}
private void MeeasureTest(List<UIElement> list, Size availableSize)
{
Stopwatch watch = Stopwatch.StartNew();
//Parallel.ForEach(list, element =>
//{
// if (element != null && !element.IsArrangeValid)
// {
// element.Measure(availableSize);
// }
//});
foreach (UIElement element in list)
{
this.Dispatcher.BeginInvoke((Action)delegate ()
{
if (element != null)
{
element.Measure(availableSize);
}
});
}
watch.Stop();
Console.WriteLine("Measure " + DateTime.Now.ToLongTimeString() + " - " + watch.ElapsedMilliseconds);
}
事实证明,如果我使用并行。如果我在foreach内使用dispatcher.begininvoke,它将尽快执行。但是所有的矩形仍然需要30s+才能显示,我想在UI线程中,它仍然需要一个一个一个。
我在尝试错误的方向吗?谁能给一些提示?
There's a function to draw over 10k different size rects that i try to speed up.
Rects are divided in groups, and each group may contains over 1k rects.
It takes 30s+ to draw all the rects, about 20s+ on MeasureOverride() and 10s+ on ArrangeOverride(). It takes a lot time to do the foreach, when the base.InternalChildren (aka a group) has hundreds even thousands of rects.
public class MyPanel : Panel
{
protected override Size MeasureOverride(Size constraint)
{
Size availableSize = new Size(double.PositiveInfinity, double.PositiveInfinity);
foreach (UIElement element in base.InternalChildren)
{
if (element != null)
{
element.Measure(availableSize);
}
}
return new Size();
}
protected override Size ArrangeOverride(Size finalSize)
{
foreach (UIElement element in base.InternalChildren)
{
if (!element.IsMeasureValid)
continue;
var x = GetX(element);
var y = GetY(element);
var width = element.DesiredSize.Width;
var height = element.DesiredSize.Height;
element.Arrange(new Rect(x - width * 0.5, y - height * 0.5, width, height));
}
return finalSize;
}
}
this derived class from Panel has a lot function on it, I can't simply replace it with a rectangle or border. So I try to do the foreach out of it, like this:
protected override Size MeasureOverride(Size constraint)
{
var list = base.InternalChildren.Cast<UIElement>().ToList();
Size availableSize = new Size(double.PositiveInfinity, double.PositiveInfinity);
MeeasureTest(list, constraint);
return new Size();
}
private void MeeasureTest(List<UIElement> list, Size availableSize)
{
Stopwatch watch = Stopwatch.StartNew();
//Parallel.ForEach(list, element =>
//{
// if (element != null && !element.IsArrangeValid)
// {
// element.Measure(availableSize);
// }
//});
foreach (UIElement element in list)
{
this.Dispatcher.BeginInvoke((Action)delegate ()
{
if (element != null)
{
element.Measure(availableSize);
}
});
}
watch.Stop();
Console.WriteLine("Measure " + DateTime.Now.ToLongTimeString() + " - " + watch.ElapsedMilliseconds);
}
It turns out, if I use Parallel.Foreach, it'll cause a thread exception. if I use Dispatcher.BeginInvoke inside the foreach, it'll execute soon. BUT all the rects still need 30s+ to be shown, i guess in the UI thread it still need to be measured one by one.
Am I trying the wrong direction? Can anyone give some tips pls?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论