平行的.在c#中使用字典和多个局部变量的ForEach

本文关键字:局部变量 ForEach 字典 | 更新日期: 2023-09-27 17:49:30

我正在尝试将普通函数转换为并行函数。

函数检查给定的坐标是否足够接近,是否认为它们是重复的,在完整的坐标列表中逐一检查。

我需要访问3个本地变量:

  • 待测坐标(poi_data)
  • 坐标表(pois)
  • 表示被认为是重复的距离的应用变量(Config.duplicatedRange)

一旦检测到重复,该函数应停止检查并返回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;
}

我得到一个错误

错误CS0452:类型bool必须是引用类型,以便将其用作泛型类型或方法System.Threading.Interlocked.Exchange<T>(ref T, 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);
}

平行的.在c#中使用字典和多个局部变量的ForEach

基本上:没有将接受bool作为参数类型的Interlocked.Exchange()方法的重载。所有显式类型方法重载都不包括bool,因此编译器尝试匹配泛型方法重载,但由于类型参数的泛型约束,这样做会失败。

最简单的替代方法是不使用bool作为result变量的类型。将其设置为int,初始化为0,如果找到要查找的项目,则将其设置为1


(我没有仔细研究你代码中的整体实现。乍一看,它似乎很好,而且您的问题似乎是专门关于错误消息的,所以我只在上面解决这个问题)。