C# Azure持久函数中RaiseEventAsync方法的InstanceId从何处获取?
我正在学习如何使用Azure持久功能,但遇到了一个问题。我正在将消息发布到队列并等待它,然后将其记录到跟踪中,但我不确定从何处获取InstanceId 以下是我目前掌握的情况:C# Azure持久函数中RaiseEventAsync方法的InstanceId从何处获取?,c#,azure,azure-functions,azure-queues,C#,Azure,Azure Functions,Azure Queues,我正在学习如何使用Azure持久功能,但遇到了一个问题。我正在将消息发布到队列并等待它,然后将其记录到跟踪中,但我不确定从何处获取InstanceId 以下是我目前掌握的情况: public static class Go { private const string ReceivedMessage = "received-message"; [FunctionName(nameof(Go))] public static async Task Run(
public static class Go
{
private const string ReceivedMessage = "received-message";
[FunctionName(nameof(Go))]
public static async Task Run(
[OrchestrationTrigger] DurableOrchestrationContext context,
TraceWriter log)
{
var message = await context.WaitForExternalEvent<string>(ReceivedMessage);
log.Info($"Received message: {message}");
}
[FunctionName(nameof(GetMessageFromQueue))]
public static async Task GetMessageFromQueue(
[QueueTrigger("messages")] string message,
[OrchestrationClient] DurableOrchestrationClient client)
{
await client.RaiseEventAsync("InstanceId", ReceivedMessage, message); // <- here
}
}
更新:
上面的代码只是一个概念证明,看看持久功能是否满足我的需求。到目前为止,我还不确定,但我想做的是:
我要排两个队
队列A将添加少量A,我打算回收这些A
队列B将有一个由外部源推送到它的不确定(出于所有目的和目的,无限)数量的B
我希望编排器等待来自这两个队列的输入,然后将A和B发送到另一个函数,该函数将生成多个B。然后,该函数将B推送到队列B,然后将A推回到队列A。该过程随后重复
我希望根据我拥有的A的数量进行并行处理。在我看来,我有两个选择: A) 创建一个使用取自常量的InstanceId创建的Orchestrator。然后,侦听A和B队列的函数将知道用于
RaiseEventAsync
调用的InstanceId
问题:不是平行的
B) 将instanceId包装在A中。每个A创建一个Orchestrator。A知道要使用哪个Orchestrator,现在每个Orchestrator都可以侦听队列B
问题:B不知道将哪个InstanceId用于
RaiseEventAsync
调用 任何将消息放在队列上并将触发您的GetMessageFromQueue
的操作都需要了解它试图指向的实例,然后我希望您在消息本身中包含实例ID
在上面列出的特定场景中,我实际上希望基于HttpTrigger
的函数返回一个包含实例ID的主体。现在您返回的是HttpResponseMessage
所创建的CreateCheckStatusResponse
,但是这被记录为返回一个202
状态,并带有一个Location
头,告诉人们在哪里可以检查编排实例的状态。虽然这些信息可能对传回也很有用,但您确实需要传回实例ID
一种方法是创建自己的
HttpResponseMessage
,其中包含一个强类型消息体,该消息体将实例ID作为属性。如果您这样做了,那么调用程序将能够从响应体中提取该ID,然后将其包含在他们放入队列的消息中,这样您的GetMessageFromQueue
函数就可以将其提取出来,传递到RaiseEventAsync
该队列中的所有消息是否都属于同一个编排ID?或者每封邮件的回答应该有所不同吗?@Mikhail我不能直接回答你,因为我不明白这个问题。但是,我只打算将消息从GetMessageFromQueue
函数发送到Go
函数。好的,问题是您是同时拥有一个实例ID还是多个实例ID?@Mikhail我不知道。我怎么能找到呢?这就是为什么我要问:)如果你需要按照你的要求有很多这样的东西,你需要把它作为队列消息的一部分传递。明白了。让我解释一下情况。我要排两个队。队列A将添加少量A,我打算回收这些A。队列B将有一个由外部源推送到它的不确定(出于所有目的和目的,无限)数量的B。我希望编排器等待来自这两个队列的输入,然后将A和B发送到另一个函数,该函数将生成多个B。然后,它会将B推送到队列B,然后将A推回到队列A。该过程随后会重复。我希望根据我拥有的A的数量,该处理是并行的。在我看来,我有两个选项:A)创建一个orchestrator,该orchestrator使用取自常量的instanceId创建。然后,侦听A和B队列的函数将知道用于RaiseEventAsync
调用的instanceId。问题:不是平行的。B) 将instanceId包装在A中。为每个A创建一个orchestrator。A知道要使用哪个orchestrator,现在每个orchestrator都可以侦听队列B。问题:B不知道要将哪个instanceId用于RaiseEventAsync
调用。我觉得我陷入了困境。好吧,让我想一想。同时,我建议你用这些细节来更新你的原始问题,这样任何遇到问题的人都不会错过这些细节,因为它们有助于更清晰地描绘出你的目标。
public static class HttpStartSingle
{
[FunctionName(nameof(HttpStartSingle))]
public static async Task<HttpResponseMessage> RunSingle(
[HttpTrigger(
AuthorizationLevel.Function,
"get", "post",
Route = "orchestrators/{functionName}")]
HttpRequestMessage req,
[OrchestrationClient] DurableOrchestrationClient starter,
string functionName,
TraceWriter log)
{
var eventData = await req.Content.ReadAsAsync<object>();
var instanceId = await starter.StartNewAsync(functionName, eventData);
return starter.CreateCheckStatusResponse(req, instanceId);
}
}
public class Program
{
public static async Task Main(string[] args)
{
Thread.Sleep(TimeSpan.FromSeconds(5));
var request = WebRequest.Create("http://localhost:7071/api/orchestrators/Go");
request.Timeout = Convert.ToInt32(TimeSpan.FromMinutes(1).TotalSeconds);
request.ContentLength = 0;
request.Method = "POST";
var json = string.Empty;
using (var response = await request.GetResponseAsync())
using (var stream = response.GetResponseStream())
{
if (stream != null)
{
using (var reader = new StreamReader(stream, Encoding.UTF8))
{
if (reader.Peek() > -1)
{
json = await reader.ReadToEndAsync();
}
}
}
}
Console.WriteLine(json);
var storageAccount = CloudStorageAccount.DevelopmentStorageAccount;
var queueuClient = storageAccount.CreateCloudQueueClient();
var queue = queueuClient.GetQueueReference("messages");
await queue.CreateIfNotExistsAsync();
await queue.AddMessageAsync(new CloudQueueMessage("This is a test message"));
Console.ReadKey();
}
}