Parallel.ForEach 在 C# 中使用字典和多个局部变量
Parallel.ForEach with Dictionary and multiple local variables in C#
我正在尝试将普通函数转换为并行函数。
该函数检查给定的坐标是否足够接近以认为它们重复,并在完整的坐标列表中逐一检查。
我需要访问 3 个局部变量:
- 待测坐标(
poi_data
)
- 坐标列表(
pois
)
- 指示被视为重复的距离的应用程序变量(
Config.duplicatedRange
)
一旦检测到重复项,该函数应停止检查并且 return true
.
这是我当前的代码。
class Test
{
public static Boolean CheckDuplicated (POIData poi_data,
Dictionary<string, POIData> pois)
{
foreach (KeyValuePair<string, POIData> item in pois)
{
Double distance = CalculateDistance (poi_data.latitude,
poi_data.longitude,
item.Value.latitude,
item.Value.longitude);
if (distance < Config.duplicatedRange) {
return true;
}
}
return false;
}
}
public class POIData
{
public Double longitude { set; get; }
public Double latitude { set; get; }
}
这是我并行进行的尝试。
public static Boolean CheckDuplicated (POIData poi_data,
Dictionary<string, POIData> pois)
{
Boolean result = false;
CancellationTokenSource cts = new CancellationTokenSource ();
ParallelOptions options = new ParallelOptions
{ CancellationToken = cts.Token };
Parallel.ForEach (pois,
options,
() => false,
(item, loopState, localCount) => {
cts.Token.ThrowIfCancellationRequested ();
Double distance = CalculateDistance (poi_data.latitude,
poi_data.longitude,
item.Value.latitude,
item.Value.longitude);
if (distance < Config.duplicatedRange) {
cts.Cancel ();
return true;
}
return false;
},
(tempResult) => {
if (tempResult == true) {
Interlocked.Exchange (ref result, tempResult);
}
});
return result;
}
我收到一个错误
Error CS0452: The type bool
must be a reference type in order to use it as type parameter T
in the generic type or method System.Threading.Interlocked.Exchange<T>(ref T, T)
我做错了什么?这是最好的方法还是有更简单的方法?
编辑:
感谢您的帮助,这里是更新后的可用功能:)
public static Boolean CheckDuplicated (POIData poi_data,
Dictionary<string, POIData> pois)
{
int result = 0;
Parallel.ForEach (pois,
() => 0,
(item, loopState, tempResult) => {
Double distance = CalculateDistance (poi_data.latitude,
poi_data.longitude,
item.Value.latitude,
item.Value.longitude);
if (distance < Config.duplicatedRange) {
loopState.Stop ();
return 1;
}
return 0;
},
(tempResult) => {
if (tempResult == 1) {
Interlocked.Exchange (ref result, tempResult);
}
});
return Convert.ToBoolean (result);
}
基本上:Interlocked.Exchange()
方法没有接受 bool
作为参数类型的重载。 None 的显式类型方法重载包括 bool
,因此编译器尝试匹配泛型方法重载,但由于类型参数的泛型约束而失败。
最简单的替代方法就是不使用 bool
作为 result
变量的类型。将其设为 int
,将其初始化为 0
,如果您找到要查找的项目,则将其设置为 1
。
(我没有仔细看你代码中的整体实现,乍一看还好,而且你的问题似乎是专门针对错误信息的,所以我只在上面解决)。
我正在尝试将普通函数转换为并行函数。
该函数检查给定的坐标是否足够接近以认为它们重复,并在完整的坐标列表中逐一检查。
我需要访问 3 个局部变量:
- 待测坐标(
poi_data
) - 坐标列表(
pois
) - 指示被视为重复的距离的应用程序变量(
Config.duplicatedRange
)
一旦检测到重复项,该函数应停止检查并且 return true
.
这是我当前的代码。
class Test
{
public static Boolean CheckDuplicated (POIData poi_data,
Dictionary<string, POIData> pois)
{
foreach (KeyValuePair<string, POIData> item in pois)
{
Double distance = CalculateDistance (poi_data.latitude,
poi_data.longitude,
item.Value.latitude,
item.Value.longitude);
if (distance < Config.duplicatedRange) {
return true;
}
}
return false;
}
}
public class POIData
{
public Double longitude { set; get; }
public Double latitude { set; get; }
}
这是我并行进行的尝试。
public static Boolean CheckDuplicated (POIData poi_data,
Dictionary<string, POIData> pois)
{
Boolean result = false;
CancellationTokenSource cts = new CancellationTokenSource ();
ParallelOptions options = new ParallelOptions
{ CancellationToken = cts.Token };
Parallel.ForEach (pois,
options,
() => false,
(item, loopState, localCount) => {
cts.Token.ThrowIfCancellationRequested ();
Double distance = CalculateDistance (poi_data.latitude,
poi_data.longitude,
item.Value.latitude,
item.Value.longitude);
if (distance < Config.duplicatedRange) {
cts.Cancel ();
return true;
}
return false;
},
(tempResult) => {
if (tempResult == true) {
Interlocked.Exchange (ref result, tempResult);
}
});
return result;
}
我收到一个错误
Error CS0452: The type
bool
must be a reference type in order to use it as type parameterT
in the generic type or methodSystem.Threading.Interlocked.Exchange<T>(ref T, T)
我做错了什么?这是最好的方法还是有更简单的方法?
编辑:
感谢您的帮助,这里是更新后的可用功能:)
public static Boolean CheckDuplicated (POIData poi_data,
Dictionary<string, POIData> pois)
{
int result = 0;
Parallel.ForEach (pois,
() => 0,
(item, loopState, tempResult) => {
Double distance = CalculateDistance (poi_data.latitude,
poi_data.longitude,
item.Value.latitude,
item.Value.longitude);
if (distance < Config.duplicatedRange) {
loopState.Stop ();
return 1;
}
return 0;
},
(tempResult) => {
if (tempResult == 1) {
Interlocked.Exchange (ref result, tempResult);
}
});
return Convert.ToBoolean (result);
}
基本上:Interlocked.Exchange()
方法没有接受 bool
作为参数类型的重载。 None 的显式类型方法重载包括 bool
,因此编译器尝试匹配泛型方法重载,但由于类型参数的泛型约束而失败。
最简单的替代方法就是不使用 bool
作为 result
变量的类型。将其设为 int
,将其初始化为 0
,如果您找到要查找的项目,则将其设置为 1
。
(我没有仔细看你代码中的整体实现,乍一看还好,而且你的问题似乎是专门针对错误信息的,所以我只在上面解决)。