我正在使用队列存储、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/