强制异步并行循环立即停止-C#

时间:2018-08-05 15:49:44

标签: c# parallel.foreach

这是我从Azures FaceAPI请求信息的方法。

我终于意识到,为了使我的应用程序更好地工作,必须并行抓取一堆我的安全摄像机框架,然后将其发送到神经网络进行分析。

(注意:这是Alexa的自定义技能,因此会在8到10秒左右超时)

因为我并行并异步地抓取了一堆帧,所以无法知道哪个图像将返回不错的人脸检测。但是,如果检测到良好的检测结果,并且请求返回了Face Data,则无法阻止其余信息返回。

发生这种情况是因为安全摄像头图像是并行发送的,它们消失了,无论如何信息都会返回。

您将看到我能够使用“线程局部变量”来捕获信息,并将其发送回功能范围为“ imageAnalysis”的变量,以进行序列化并允许Alexa在安全映像中描述人员。但是,因为循环处于并行状态,所以不会立即中断。 可能只需要一两秒钟,但是由于Alexas严格的超时政策,所以我有时间限制。

似乎没有办法立即中断并行循环...

还是在那里?

收集“ imageAnalysis”数据花费的时间越多,Alexa等待响应的时间就越长。她的等待时间不长,因此在Alexa超时之前,尝试发送尽可能多的图像进行分析非常重要,并且还要保持在Azure FaceAPI限制之内。

        public static async Task<List<Person>> DetectPersonAsync()
    {
        ConfigurationDto config = Configuration.Configuration.GetSettings();

        string imageAnalysis;
        using (var cameraApi = new SecurityCameraApi())
        {
            byte[] imageData = cameraApi.GetImageAsByte(config.SecurityCameraUrl +
                                                        config.SecurityCameraStaticImage +
                                                        DateTime.Now);

            //Unable to get an image from the Security Camera
            if (!imageData.Any())
            {
                Logger.LogInfo(Logger.LogType.Info, "Unable to aquire image from Security Camera \n");

                return null;
            }

            Logger.LogInfo(Logger.LogType.Info, "Attempting Image Face Detection...\n");


            Func<string, bool> isEmptyOrErrorAnalysis = s => s.Equals("[]") || s.Contains("error");


            imageAnalysis = "[]";

            List<byte[]> savedImageList = cameraApi.GetListOfSavedImagesAsByte();

            if (savedImageList.Any())
            {
                Parallel.ForEach(savedImageList, new ParallelOptions
                {
                    MaxDegreeOfParallelism = 50
                },
                    async (image, loopState) =>
                    {
                        string threadLocalImageAnalysis = "[]";
                        if (!loopState.IsStopped)
                            threadLocalImageAnalysis = await GetImageAnalysisAsync(image, config);

                        if (!isEmptyOrErrorAnalysis(threadLocalImageAnalysis))
                        {
                            imageAnalysis = threadLocalImageAnalysis;
                            loopState.Break();       
                        }
                    });
            }

            // Don't do to many image analysis - or Alexa will time-out.
            Func<List<byte[]>, int> detectionCount =
                savedImageListDetections => savedImageListDetections.Count > 5 ? 0 : 16;


            //Continue with detections of current Camera image frames
            if (isEmptyOrErrorAnalysis(imageAnalysis))
            {

                    Parallel.For(0, detectionCount(savedImageList), new ParallelOptions
                    {
                        MaxDegreeOfParallelism = 50
                    },
                        async (i, loopState) =>
                        {
                            imageData = cameraApi.GetImageAsByte(config.SecurityCameraUrl +
                                                                 config.SecurityCameraStaticImage +
                                                                 DateTime.Now);

                            string threadLocalImageAnalysis = "[]";
                            if (!loopState.IsStopped)
                                threadLocalImageAnalysis = await GetImageAnalysisAsync(imageData, config);

                            if (!isEmptyOrErrorAnalysis(threadLocalImageAnalysis))
                            {
                                imageAnalysis = threadLocalImageAnalysis;
                                loopState.Break();
                            }
                        });
            }
        }

        try
        {
            //Cognitive sense has found elements(people) in the image
            return new NewtonsoftJsonSerializer().DeserializeFromString<List<Person>>(imageAnalysis);
        }
        catch (Exception ex)
        {
            //No elements(people) detected from the camera stream
            Logger.LogInfo(Logger.LogType.Info,
                string.Format(
                    "Microsoft Cognitive Sense Face Api Reports: \n{0} \nNo people in the CCTV Camera Image.\n",
                    ex.Message));

            return new List<Person>(); //Empty
        }
    }


    private static async Task<string> GetImageAnalysisAsync(byte[] image, ConfigurationDto config)
    {
        string json;
        using (var client = new HttpClient())
        {
            client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key",
                config.MicrosoftCognitiveSenseApiKey);


            // Request parameters.
            const string queryString =
                "returnFaceId=true" +
                "&returnFaceLandmarks=false" +
                "&returnFaceAttributes=age,gender,accessories,hair";

            const string uri =
                "https://westus.api.cognitive.microsoft.com/face/v1.0/detect?" + queryString;

            using (var content = new ByteArrayContent(image))
            {
                content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");

                HttpResponseMessage response = await client.PostAsync(uri, content);

                json = await response.Content.ReadAsStringAsync();
                try
                {
                    Logger.LogInfo(Logger.LogType.Info, json);
                }
                catch
                {
                }
            }
        }
        return json;
    }

0 个答案:

没有答案