c# - 在 Azure Function Service Bus 触发器中使用异步方法

标签 c# string azure task azure-functions

我正在使用队列存储、blob 存储和带有队列触发器的 Azure 函数来创建一个项目。它包括队列接收消息的任何时候,在 blob 中拍摄同名的图片,然后使用 FaceApi 进行分析,以 Json 形式发送 ServiceBus 主题。该程序是异步的。

public static async Task<string> MakeAnalysisRequestAsync()
string valor = "";
            const string subscriptionKey = "yoursubsciptionkey";


            const string uriBase =
                "https://westeurope.api.cognitive.microsoft.com/face/v1.0/detect";

            HttpClient client = new HttpClient();

            // Request headers.
            client.DefaultRequestHeaders.Add(
                "Ocp-Apim-Subscription-Key", subscriptionKey);

            // Request parameters. A third optional parameter is "details".
            string requestParameters = "returnFaceId=true&returnFaceLandmarks=false" +
                "&returnFaceAttributes=age,gender,headPose,smile,facialHair,glasses," +
                "emotion,hair,makeup,occlusion,accessories,blur,exposure,noise";

            // Assemble the URI for the REST API Call.
            string uri = uriBase + "?" + requestParameters;

            HttpResponseMessage response;

            //forearch element in yourqueue, search in blob storage and make an analysis
            CloudStorageAccount storageAccount = new CloudStorageAccount(
new Microsoft.WindowsAzure.Storage.Auth.StorageCredentials(
"yourstorage",
"connectionstorage"), true);

            CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
            CloudBlobContainer container = blobClient.GetContainerReference("yourstorage");



            // Create the queue client
            CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();

            // Retrieve a reference to a queue
            CloudQueue queue = queueClient.GetQueueReference("yourqueue");

            // Get the next message
            CloudQueueMessage retrievedMessage = await queue.GetMessageAsync();

            string prueba = retrievedMessage.AsString;
            CloudBlockBlob blockBlob = container.GetBlockBlobReference(prueba);

            var uriblob = blockBlob.Uri.AbsoluteUri;
            var webClient = new WebClient();
            byte[] imageBytesuri = webClient.DownloadData(uriblob);


            using (ByteArrayContent content = new ByteArrayContent(imageBytesuri))
            {

                content.Headers.ContentType =
                    new MediaTypeHeaderValue("application/octet-stream");

                // Execute the REST API call.
                response = await client.PostAsync(uri, content);

                // Get the JSON response.
                string contentString = await response.Content.ReadAsStringAsync();
                valor = contentString;

            }
            return valor;
} 





它工作正常,例如,如果队列中有一条名为 Darren.png 的消息,它将返回 blob 存储中图片 Darren.png 的面部分析,如下所示

[{"faceId":"45 345345435","faceRectangle":{"top":84,"left":98,"width":83,"height":83},"faceAttributes":{"smile":1.0,"headPose":{"pitch":-11.3,"roll":8.4,"yaw":-9.4},"gender":"male","age":48.0,"facialHair":{"moustache":0.1,"beard":0.1,"sideburns":0.1},"glasses":"NoGlasses","emotion":{"anger":0.0,"contempt":0.0,"disgust":0.0,"fear":0.0,"happiness":1.0,"neutral":0.0,"sadness":0.0,"surprise":0.0},"blur":{"blurLevel":"low","value":0.0},"exposure":{"exposureLevel":"overExposure","value":0.83},"noise":{"noiseLevel":"low","value":0.08},"makeup":{"eyeMakeup":false,"lipMakeup":false},"accessories":[],"occlusion":{"foreheadOccluded":false,"eyeOccluded":false,"mouthOccluded":false},"hair":{"bald":0.13,"invisible":false,"hairColor":[{"color":"brown","confidence":1.0},{"color":"red","confidence":0.66},{"color":"blond","confidence":0.25},{"color":"black","confidence":0.16},{"color":"gray","confidence":0.13},{"color":"other","confidence":0.03}]}}}]

现在,我创建了一个带有队列触发器的 AzureFunction 并加载分析程序“faceApiCorregido”。

[FunctionName("Function1")]
        public static void Run([QueueTrigger("yourqueue", Connection = "AzureWebJobsStorage")]string myQueueItem, TraceWriter log)
        {
           string messageBody =  Funciones.MakeAnalysisRequestAsync().ToString();

            //Task<string> messageBody2 =  Funciones.MakeAnalysisRequestAsync();
            //string messageBody1 = await messageBody.GetResult();
            log.Info($"C# Queue trigger function processed: {myQueueItem}");
            const string ServiceBusConnectionString = "yourconnectionstring";
            const string TopicName = "topicfoto";
            ITopicClient topicClient;
            topicClient = new TopicClient(ServiceBusConnectionString, TopicName);

            // Create a new message to send to the topic
            //string messageBody =  FaceApiLibreriaCoreFoto.Funciones.MakeAnalysisRequestAsync().ToString();

           // string messageBody = FaceApiCorregido.Funciones.MakeAnalysisRequestAsync().ToString(); 
            var message = new Message(Encoding.UTF8.GetBytes(messageBody));

            // Write the body of the message to the console
            Console.WriteLine($"Sending message: {messageBody}");

            // Send the message to the topic
             topicClient.SendAsync(message);


        }

但这不起作用,我需要一个字符串而不是任务。我尝试了不同的方法来修复它,但它不起作用,例如,如果我写

string messageBody =  Funciones.MakeAnalysisRequestAsync().ToString();

它会返回类似的内容

System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1+AsyncStateMachineBox`1[System.String,FaceApiCorregido.Funciones+<MakeAnalysisRequestAsync>d__1]

我也尝试过 getResult().getAwaiter() 但有错误。最后,我尝试使我的 AzureFunction 异步,但也给了我一个错误,如 System.Private.CoreLib: 执行函数时出现异常:Function1。 FaceApiCorregido:未将对象引用设置为对象的实例。 我知道这是一个常见问题,并且有很多解决它的信息,但我不知道如何解决。有人可以帮助我吗? 谢谢你的优势。

最佳答案

如果你想让它同步运行,只需调用

string messageBody =  Funciones.MakeAnalysisRequestAsync().Result;

如果异步:

string messageBody =  await Funciones.MakeAnalysisRequestAsync();

异步方法不直接返回结果。相反,它们返回一个任务,您必须通过等待关键字等待它完成,这将释放当前线程并在任务完成后恢复,或者仅调用结果,这将阻止当前执行,直到结果可用。

关于c# - 在 Azure Function Service Bus 触发器中使用异步方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57216003/

相关文章:

Java - 小写引号外的字符串

c# - C#中的另一种获取属性名(这个是静态的)

c# - 在数据网格中搜索

javascript - 如何将 C# 变量传递给 JavaScript 函数

java - 查看字符串是否包含所有数字的方法

c++ - 在源代码中嵌入较长文本的技巧,如 Perl 等语言?

c# - SAFE Pointer to a pointer (well reference to a reference) 在 C# 中

azure - 无法登录 Skype Web SDK 示例

azure - OAuth2 流程中 AAD 的 access_token 错误

Azure DevOps 管道 - 获取前一阶段的内部版本号