这是我在StackOverflow上的第一篇文章,所以...你好伙计们:)
我在与TPL库挣扎。我想使用下面的Parallel.For()方法绘制图形线:
Parallel.For(minRangeIndex, maxRangeIndex + 1, (i, loopState) =>
{
if (i + 1 <= graphDataPoints.Count - 1)
{
double x1 = (graphDataPoints[i].X * i * TotalImageScale) + ImagePosition.X;
double y1 = (graphDataPoints[i].Y * TotalImageScale) + ImagePosition.Y;
double x2 = (graphDataPoints[i + 1].X * (i + 1) * TotalImageScale) + ImagePosition.X;
double y2 = (graphDataPoints[i + 1].Y * TotalImageScale) + ImagePosition.Y;
graphLine = new Line();
graphLine.X1 = x1;
graphLine.Y1 = y1;
graphLine.X2 = x2;
graphLine.Y2 = y2;
graphLine.StrokeThickness = 8;
graphLine.Stroke = graphLineBrush;
graphLine.StrokeStartLineCap = lineCap;
graphLine.StrokeEndLineCap = lineCap;
dummyCanv.Children.Add(graphLine);
indicator = new Ellipse();
indicator.Width = 10;
indicator.Height = 10;
indicator.Fill = axisLineBrush;
indicator.SetValue(Canvas.TopProperty, y1 - 5);
indicator.SetValue(Canvas.LeftProperty, x1 - 5);
indicator.Tap += indicator_Tap;
//Canvas.SetTop(indicator, y1 - 5);
//Canvas.SetLeft(indicator, x1 - 5);
dummyCanv.Children.Add(indicator);
if (i % 2 == 0)
{
xAxisLabel = new TextBlock();
xAxisLabel.Text = "" + graphDataPoints[i].label;
xAxisLabel.Foreground = labelBrush;
xAxisLabel.SetValue(Canvas.LeftProperty, x1 + xAxisLabelHorizonralOffset);
//Canvas.SetLeft(xAxisLabel, x1 + xAxisLabelHorizonralOffset);
XAxis.Children.Add(xAxisLabel);
}
xAxisLabelLine = new Line();
xAxisLabelLine.StrokeThickness = 4;
xAxisLabelLine.Stroke = axisLineBrush;
xAxisLabelLine.X1 = x1;
xAxisLabelLine.Y1 = 0;
xAxisLabelLine.X2 = x1;
xAxisLabelLine.Y2 = 6;
XAxis.Children.Add(xAxisLabelLine);
}
else
{
loopState.Break();
}
});
但我得到例外MethodAccessException : Attempt to access the method failed: System.Environment.get_ProcessorCount()
我在MSDN上读到Silverlight for WP中的ProcessorCount属性具有SecurityCriticalAttribute属性并使用它会导致MethodAccessException(http://msdn.microsoft.com/en-us/library/system.environment.processorcount%28v=vs.95%29.aspx) 所以我想知道如何在WP7应用程序中使用TPL库和Parallel.For()方法?有没有人有这个问题?
更新 我试过使用Task.Run并做了一些像这样的事情:
try
{
Task.Run(() =>
{
double limitRectHeight = dummyCanvHeight * 0.9 * TotalImageScale * (Defines.limitPromili / maxPromilValue);
limitRect = new Rectangle();
limitRect.Width = dummyCanvWidth;
limitRect.Height = limitRectHeight;
limitRect.Fill = limitRectBrush;
limitRect.Opacity = 0.3;
limitRect.SetValue(Canvas.TopProperty, dummyCanvHeight * TotalImageScale - limitRectHeight + ImagePosition.Y);
//Canvas.SetTop(limitRect, dummyCanvHeight * TotalImageScale - limitRectHeight + ImagePosition.Y);
//dummyCanv.Children.Add(limitRect);
Dispatcher.BeginInvoke(() =>
{
dummyCanv.Children.Add(limitRect);
});
});
}
catch (AggregateException ae)
{
}
但它不起作用,不绘制Rectangle并抛出AggregateException。基本上我要做的是提高我的绘图循环的性能,它被实现为DispatcherTimer Tick事件处理程序,如下所示:
private void drawChart()
{
visibleLines = (int)(dummyCanvWidth / (pointsSpacing * TotalImageScale));
if (ImagePosition.X >= 0) firstVisiblePointIndex = 0;
else firstVisiblePointIndex = Math.Abs((int)((ImagePosition.X) / (pointsSpacing * TotalImageScale))) + 1;
visibleMinIndex = firstVisiblePointIndex;
visibleMaxIndex = visibleMinIndex + visibleLines;
if (visibleMaxIndex > graphDataPoints.Count - 1) visibleMaxIndex = graphDataPoints.Count - 1;
minRangeIndex = visibleMinIndex;
maxRangeIndex = visibleMaxIndex;
if (visibleMinIndex != 0) minRangeIndex -= 1;
if (visibleMaxIndex < graphDataPoints.Count - 1) maxRangeIndex += 1;
if (minRangeIndex < 0) minRangeIndex = 0;
if (maxRangeIndex > graphDataPoints.Count - 1) maxRangeIndex = graphDataPoints.Count - 1;
dummyCanv.Children.Clear();
XAxis.Children.Clear();
double limitRectHeight = dummyCanvHeight * 0.9 * TotalImageScale * (Defines.limitPromili / maxPromilValue);
limitRect = new Rectangle();
limitRect.Width = dummyCanvWidth;
limitRect.Height = limitRectHeight;
limitRect.Fill = limitRectBrush;
limitRect.Opacity = 0.3;
limitRect.SetValue(Canvas.TopProperty, dummyCanvHeight * TotalImageScale - limitRectHeight + ImagePosition.Y);
//Canvas.SetTop(limitRect, dummyCanvHeight * TotalImageScale - limitRectHeight + ImagePosition.Y);
dummyCanv.Children.Add(limitRect);
for (int i = minRangeIndex; i <= maxRangeIndex; i++)
{
if (i + 1 <= graphDataPoints.Count - 1)
{
double x1 = (graphDataPoints[i].X * i * TotalImageScale) + ImagePosition.X;
double y1 = (graphDataPoints[i].Y * TotalImageScale) + ImagePosition.Y;
double x2 = (graphDataPoints[i + 1].X * (i + 1) * TotalImageScale) + ImagePosition.X;
double y2 = (graphDataPoints[i + 1].Y * TotalImageScale) + ImagePosition.Y;
graphLine = new Line();
graphLine.X1 = x1;
graphLine.Y1 = y1;
graphLine.X2 = x2;
graphLine.Y2 = y2;
graphLine.StrokeThickness = 8;
graphLine.Stroke = graphLineBrush;
graphLine.StrokeStartLineCap = lineCap;
graphLine.StrokeEndLineCap = lineCap;
dummyCanv.Children.Add(graphLine);
indicator = new Ellipse();
indicator.Width = 10;
indicator.Height = 10;
indicator.Fill = axisLineBrush;
indicator.SetValue(Canvas.TopProperty, y1 - 5);
indicator.SetValue(Canvas.LeftProperty, x1 - 5);
indicator.Tap += indicator_Tap;
dummyCanv.Children.Add(indicator);
if (i % 2 == 0)
{
xAxisLabel = new TextBlock();
xAxisLabel.Text = "" + graphDataPoints[i].label;
xAxisLabel.Foreground = labelBrush;
xAxisLabel.SetValue(Canvas.LeftProperty, x1 + xAxisLabelHorizonralOffset);
//Canvas.SetLeft(xAxisLabel, x1 + xAxisLabelHorizonralOffset);
XAxis.Children.Add(xAxisLabel);
}
xAxisLabelLine = new Line();
xAxisLabelLine.StrokeThickness = 4;
xAxisLabelLine.Stroke = axisLineBrush;
xAxisLabelLine.X1 = x1;
xAxisLabelLine.Y1 = 0;
xAxisLabelLine.X2 = x1;
xAxisLabelLine.Y2 = 6;
XAxis.Children.Add(xAxisLabelLine);
}
else
{
break;
}
}
if (xAxisLine == null)
{
xAxisLine = new Line();
xAxisLine.StrokeThickness = 4;
xAxisLine.Stroke = axisLineBrush;
xAxisLine.X1 = 0;
xAxisLine.X2 = XAxis.ActualWidth;
xAxisLine.Y1 = 0;
xAxisLine.Y2 = 0;
XAxis.Children.Add(xAxisLine);
}
else
{
XAxis.Children.Add(xAxisLine);
}
if (yAxisLine == null)
{
yAxisLine = new Line();
yAxisLine.StrokeThickness = 4;
yAxisLine.Stroke = axisLineBrush;
yAxisLine.X1 = yAxisCanvWidth;
yAxisLine.Y1 = 0;
yAxisLine.X2 = yAxisCanvWidth;
yAxisLine.Y2 = yAxisCanvHeight;
YAxis.Children.Add(yAxisLine);
}
if (promilLabel == null)
{
promilLabel = new TextBlock();
promilLabel.Text = "\u2030";
promilLabel.Foreground = labelBrush;
YAxis.Children.Add(promilLabel);
}
double val = maxPromilValue / 5;
for (int i = 0; i <= 5; i++)
{
double top = ((dummyCanvHeight - (dummyCanvHeight * (i * val) * 0.9 / maxPromilValue)) * TotalImageScale) + ImagePosition.Y;
yAxisLabel = new TextBlock();
yAxisLabel.Text = String.Format("{0:N2}", (i * val));
yAxisLabel.Foreground = labelBrush;
yAxisLabel.SetValue(Canvas.TopProperty, top);
yAxisLabel.SetValue(Canvas.LeftProperty, 5d);
//Canvas.SetTop(yAxisLabel, top);
//Canvas.SetLeft(yAxisLabel, 5);
dummyCanv.Children.Add(yAxisLabel);
yAxisLabelLine = new Line();
yAxisLabelLine.Stroke = axisLineBrush;
yAxisLabelLine.StrokeThickness = 4;
yAxisLabelLine.X1 = 0;
yAxisLabelLine.X2 = 6;
yAxisLabelLine.Y1 = top;
yAxisLabelLine.Y2 = top;
dummyCanv.Children.Add(yAxisLabelLine);
}
}
也许你能指出一些性能优化?