WP7:任务并行库MethodAccessException

时间:2013-08-01 13:52:34

标签: c# silverlight windows-phone-7 windows-phone

这是我在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);
        }
    }

也许你能指出一些性能优化?

0 个答案:

没有答案