代码之家  ›  专栏  ›  技术社区  ›  SBFrancies

是否有一种方法可以在持久函数中等待外部事件,而无需重放长时间运行的任务

  •  0
  • SBFrancies  · 技术社区  · 5 年前

    我遇到了一个问题,需要立即执行一个长时间运行的任务,然后在稍后使用长时间运行任务的结果执行一个快速任务。我想我可以用Azure持久功能做这样的事情:

    [FunctionName("MyFunction")]
    public static async Task RunOrchestrator([OrchestrationTrigger] IDurableOrchestrationContext context)
    {
        var myThing = LongRunningTask();
    
        var result = await context.WaitForExternalEvent<object>("SomeEvent");
    
        myThing.DoSomething(result);
    }
    

    我误解了函数的工作原理,现在意识到每次触发外部事件时,我的长时间运行任务都会被重放。这显然不是理想的行为。

    有什么方法可以用持久函数或其他类型的资源来实现我想要的吗?不幸的是,在这种情况下,长时间运行任务的结果( myThing 上面)不能序列化,我认为这会简化事情。

    0 回复  |  直到 5 年前
        1
  •  0
  •   Anthony Chu    5 年前

    您不应该在编排器中执行任何其他简单、确定的逻辑。将所有使用I/O或CPU密集型的东西移动到活动功能。活动函数的结果在编排器中被捕获和回放,而无需再次重新运行活动函数。

    [FunctionName("MyFunction")]
    public static async Task RunOrchestrator([OrchestrationTrigger] IDurableOrchestrationContext context)
    {
        var myThing = await context.CallActivityAsync<Thing>("LongRunningTask", null);
    
        var result = await context.WaitForExternalEvent<object>("SomeEvent");
    
        myThing.DoSomething(result);
    }
    
    // Thing needs to be serializable
    public class Thing
    {
        public string MyData { get; set; }
        public void DoSomething()
        {
            // do something with MyData
        }
    }
    
    [FunctionName("LongRunningTask")]
    public static async Task<Thing> LongRunningTask([ActivityTrigger] IDurableActivityContext context)
    {
        // do some long running work
        var result = new Thing { MyData = myResult };
        return result;
    }
    
        2
  •  -1
  •   MKR    5 年前

    尝试使用 Task.WhenAll 等待多个任务。

    [FunctionName("MyFunction")]
    public static async Task RunOrchestrator(
                  [OrchestrationTrigger] IDurableOrchestrationContext context)
    {
        var myThingTask = Task.Run(() => LongRunningTask());
    
        var wait =  context.WaitForExternalEvent<object>("SomeEvent");
    
        await Task.WhenAll(myThingTask, wait); //Both task and external event completed.
    
        var myThing = await myThingTask;  //Get the result from task (Its completed)
    
        myThing.DoSomething(result);
    }
    
    推荐文章