Parallel.For 导致静态函数非空参数变为空
Parallel.For causing static function non-null parameter to become null
我有一个没有问题的双 for 循环,但是当我将外循环转换为 Parallel.For 时失败了……由于调用了这个函数而失败了:
NormalizationPoint.CalculateDose(
fPixel1, fPixel2, uncompensatedBeams, new Vector3D( xLocation, yLocation, PlaneZ ) );
函数具有此签名的地方:
public static double CalculateDose(
FluencePixel fluencePixel1, FluencePixel fluencePixel2,
Beam[] uncompensatedBeams, Vector3D location )
我确定不为空的 fPixel1 在 CalculateEstimatedDose 的正文中以某种方式变为空(未在任何地方设置它)。奇怪的是,fPixel2 被正常传递。这是完整的代码:
Parallel.For(0, yLength, y =>
{
for ( int x = 0; x < xLength; x++ )
{
double xLocation = ImageData.Origin.X + ( 0.5 + x ) * ImageData.XRes; // offset by half pixel to get center of pixel
double yLocation = ImageData.Origin.Y + ( 0.5 + y ) * ImageData.YRes;
Vector3D pixelLocation = new Vector3D( xLocation, yLocation, PlaneZ );
if (( fPixel1 = fluences[0].GetIntersectingFluencePixel( pixelLocation ) ) != null
&& ( fPixel2 = fluences[1].GetIntersectingFluencePixel( pixelLocation ) ) != null )
{
// I added this redundant check just to be SURE it wasn't passed in null
if ( fPixel1 == null || fPixel2 == null )
{
DosePlaneDirectBitmap.Bits[x + y * xLength] = ( alpha << 24 ) | 0x8B;
continue;
}
// HERE IS THE PROBLEM SPOT, SOMEHOW CAUSING fPixel1 TO BECOME NULL IN THE FUNCTION
double doseValue = NormalizationPoint.CalculatedDose( fPixel1, fPixel2, uncompensatedBeams, new Vector3D( xLocation, yLocation, PlaneZ ) ) / NormalizationPoint.LastEstimatedDose;
output[x, y] = doseValue;
}
else
{
//DosePlaneBitmap.SetPixel( x, y, Color.FromArgb(alpha, 0, 0, 0x8B)); // dark blue
DosePlaneDirectBitmap.Bits[x + y * xLength] = ( alpha << 24 ) | 0x8B;
}
}
}
);
同样,只需将 Parallel.For 替换为
for ( int y = 0; y < yLength; y++ )
不会导致静态 CalculateDose 函数(未以任何方式重载)内的空指针异常。有什么想法吗?
这一行将修改fPixel1
:
if (( fPixel1 = fluences[0].GetIntersectingFluencePixel( pixelLocation ) ) != null
&& ( fPixel2 = fluences[1].GetIntersectingFluencePixel( pixelLocation ) ) != null )
由于 fPixel1
似乎是在 for 循环之外声明的,所有不同的线程都可以访问它,并且其他线程可能已将其设置为 null。
我的建议是在 for 循环中声明 fPixel1
。作为一般规则,变量的范围应该尽可能小,所以我实际上会把它放在内部循环中:
Parallel.For(0, yLength, y =>
{
for ( int x = 0; x < xLength; x++ )
{
double xLocation = ImageData.Origin.X + ( 0.5 + x ) * ImageData.XRes; // offset by half pixel to get center of pixel
double yLocation = ImageData.Origin.Y + ( 0.5 + y ) * ImageData.YRes;
Vector3D pixelLocation = new Vector3D( xLocation, yLocation, PlaneZ );
FluencePixel fPixel1 = fluences[0].GetIntersectingFluencePixel( pixelLocation );
FluencePixel fPixel2 = fluences[1].GetIntersectingFluencePixel( pixelLocation );
if ( fPixel1 != null && fPixel2 != null)
{
//Etc.....
我也摆脱了 "assignment inside if condition" 因为这显然是一个令人困惑的结构。
我有一个没有问题的双 for 循环,但是当我将外循环转换为 Parallel.For 时失败了……由于调用了这个函数而失败了:
NormalizationPoint.CalculateDose(
fPixel1, fPixel2, uncompensatedBeams, new Vector3D( xLocation, yLocation, PlaneZ ) );
函数具有此签名的地方:
public static double CalculateDose(
FluencePixel fluencePixel1, FluencePixel fluencePixel2,
Beam[] uncompensatedBeams, Vector3D location )
我确定不为空的 fPixel1 在 CalculateEstimatedDose 的正文中以某种方式变为空(未在任何地方设置它)。奇怪的是,fPixel2 被正常传递。这是完整的代码:
Parallel.For(0, yLength, y =>
{
for ( int x = 0; x < xLength; x++ )
{
double xLocation = ImageData.Origin.X + ( 0.5 + x ) * ImageData.XRes; // offset by half pixel to get center of pixel
double yLocation = ImageData.Origin.Y + ( 0.5 + y ) * ImageData.YRes;
Vector3D pixelLocation = new Vector3D( xLocation, yLocation, PlaneZ );
if (( fPixel1 = fluences[0].GetIntersectingFluencePixel( pixelLocation ) ) != null
&& ( fPixel2 = fluences[1].GetIntersectingFluencePixel( pixelLocation ) ) != null )
{
// I added this redundant check just to be SURE it wasn't passed in null
if ( fPixel1 == null || fPixel2 == null )
{
DosePlaneDirectBitmap.Bits[x + y * xLength] = ( alpha << 24 ) | 0x8B;
continue;
}
// HERE IS THE PROBLEM SPOT, SOMEHOW CAUSING fPixel1 TO BECOME NULL IN THE FUNCTION
double doseValue = NormalizationPoint.CalculatedDose( fPixel1, fPixel2, uncompensatedBeams, new Vector3D( xLocation, yLocation, PlaneZ ) ) / NormalizationPoint.LastEstimatedDose;
output[x, y] = doseValue;
}
else
{
//DosePlaneBitmap.SetPixel( x, y, Color.FromArgb(alpha, 0, 0, 0x8B)); // dark blue
DosePlaneDirectBitmap.Bits[x + y * xLength] = ( alpha << 24 ) | 0x8B;
}
}
}
);
同样,只需将 Parallel.For 替换为
for ( int y = 0; y < yLength; y++ )
不会导致静态 CalculateDose 函数(未以任何方式重载)内的空指针异常。有什么想法吗?
这一行将修改fPixel1
:
if (( fPixel1 = fluences[0].GetIntersectingFluencePixel( pixelLocation ) ) != null
&& ( fPixel2 = fluences[1].GetIntersectingFluencePixel( pixelLocation ) ) != null )
由于 fPixel1
似乎是在 for 循环之外声明的,所有不同的线程都可以访问它,并且其他线程可能已将其设置为 null。
我的建议是在 for 循环中声明 fPixel1
。作为一般规则,变量的范围应该尽可能小,所以我实际上会把它放在内部循环中:
Parallel.For(0, yLength, y =>
{
for ( int x = 0; x < xLength; x++ )
{
double xLocation = ImageData.Origin.X + ( 0.5 + x ) * ImageData.XRes; // offset by half pixel to get center of pixel
double yLocation = ImageData.Origin.Y + ( 0.5 + y ) * ImageData.YRes;
Vector3D pixelLocation = new Vector3D( xLocation, yLocation, PlaneZ );
FluencePixel fPixel1 = fluences[0].GetIntersectingFluencePixel( pixelLocation );
FluencePixel fPixel2 = fluences[1].GetIntersectingFluencePixel( pixelLocation );
if ( fPixel1 != null && fPixel2 != null)
{
//Etc.....
我也摆脱了 "assignment inside if condition" 因为这显然是一个令人困惑的结构。