- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个现有的函数应用程序,其中包含 2 个函数和一个存储队列。 F1 由服务总线主题中的消息触发。对于收到的每个消息,F1 计算一些必须以不同的延迟量执行的子任务(T1,T2,...)。例如 - T1 在 3 分钟后触发,T2 在 5 分钟后触发,等等。F1 将消息发布到具有适当可见性超时的存储队列(以模拟延迟),只要消息在队列中可见,就会触发 F2。一切正常。
我现在想要迁移此应用程序以使用“耐用功能”。 F1 现在仅启动协调器。协调器代码如下 -
public static async Task Orchestrator([OrchestrationTrigger] DurableOrchestrationContext context, TraceWriter log)
{
var results = await context.CallActivityAsync<List<TaskInfo>>("CalculateTasks", "someinput");
List<Task> tasks = new List<Task>();
foreach (var value in results)
{
var pnTask = context.CallActivityAsync("PerformSubTask", value);
tasks.Add(pnTask);
}
//dont't await as we want to fire and forget. No fan-in!
//await Task.WhenAll(tasks);
}
[FunctionName("PerformSubTask")]
public async static Task Run([ActivityTrigger]TaskInfo info, TraceWriter log)
{
TimeSpan timeDifference = DateTime.UtcNow - info.Origin.ToUniversalTime();
TimeSpan delay = TimeSpan.FromSeconds(info.DelayInSeconds);
var actualDelay = timeDifference > delay ? TimeSpan.Zero : delay - timeDifference;
//will still keep the activity function running and incur costs??
await Task.Delay(actualDelay);
//perform subtask work after delay!
}
我只想扇出(不扇入来收集结果)并启动子任务。协调器启动所有任务并避免调用“await Task.WhenAll”。事件函数调用“Task.Delay”等待指定的时间,然后执行其工作。
我的问题
在此工作流程中使用 Durable Functions 是否有意义?
这是编排“扇出”工作流程的正确方法吗?
我不喜欢这样的事实:事件函数运行指定的时间(3 或 5 分钟)而不执行任何操作。会产生成本吗?
此外,如果需要延迟超过 10 分钟,则 no way事件函数要通过这种方法取得成功!
我之前尝试避免这种情况的方法是在协调器中使用“CreateTimer”,然后将该事件添加为延续,但我在“历史记录”表中只看到计时器条目。续作不火!我是否违反了 constraint for orchestrator code -“编排器代码绝不能启动任何异步操作”?
foreach (var value in results)
{
//calculate time to start
var timeToStart = ;
var pnTask = context.CreateTimer(timeToStart , CancellationToken.None).ContinueWith(t => context.CallActivityAsync("PerformSubTask", value));
tasks.Add(pnTask);
}
更新:使用克里斯建议的方法
计算子任务和延迟的事件
[FunctionName("CalculateTasks")]
public static List<TaskInfo> CalculateTasks([ActivityTrigger]string input,TraceWriter log)
{
//in reality time is obtained by calling an endpoint
DateTime currentTime = DateTime.UtcNow;
return new List<TaskInfo> {
new TaskInfo{ DelayInSeconds = 10, Origin = currentTime },
new TaskInfo{ DelayInSeconds = 20, Origin = currentTime },
new TaskInfo{ DelayInSeconds = 30, Origin = currentTime },
};
}
public static async Task Orchestrator([OrchestrationTrigger] DurableOrchestrationContext context, TraceWriter log)
{
var results = await context.CallActivityAsync<List<TaskInfo>>("CalculateTasks", "someinput");
var currentTime = context.CurrentUtcDateTime;
List<Task> tasks = new List<Task>();
foreach (var value in results)
{
TimeSpan timeDifference = currentTime - value.Origin;
TimeSpan delay = TimeSpan.FromSeconds(value.DelayInSeconds);
var actualDelay = timeDifference > delay ? TimeSpan.Zero : delay - timeDifference;
var timeToStart = currentTime.Add(actualDelay);
Task delayedActivityCall = context
.CreateTimer(timeToStart, CancellationToken.None)
.ContinueWith(t => context.CallActivityAsync("PerformSubtask", value));
tasks.Add(delayedActivityCall);
}
await Task.WhenAll(tasks);
}
简单地从协调器内部调度任务似乎是可行的。在我的例子中,我正在循环之前计算另一个事件(CalculateTasks)中的任务和延迟。我希望使用事件运行时的“当前时间”来计算延迟。我在事件中使用 DateTime.UtcNow 。在编排器中使用时,这在某种程度上表现不佳。 “ContinueWith”指定的事件不会运行,并且协调器始终处于“正在运行”状态。
我可以不使用协调器内的事件记录的时间吗?
更新2
所以克里斯建议的解决方法有效!
由于我不想收集事件的结果,因此我避免在安排所有事件后调用“await Tasks.WhenAll(tasks)
”。我这样做是为了减少控制队列上的争用,即能够在需要时启动另一个编排。尽管如此,“协调器”的状态仍然是“正在运行”,直到所有事件完成运行。我猜想只有在最后一个事件向控制队列发布“完成”消息后,它才会移动到“完成”。
我说得对吗?有没有什么办法可以更早地释放协调器,即在安排所有事件之后立即释放?
最佳答案
ContinueWith
方法对我来说效果很好。我能够使用以下编排器代码模拟您的场景的一个版本:
[FunctionName("Orchestrator")]
public static async Task Orchestrator(
[OrchestrationTrigger] DurableOrchestrationContext context,
TraceWriter log)
{
var tasks = new List<Task>(10);
for (int i = 0; i < 10; i++)
{
int j = i;
DateTime timeToStart = context.CurrentUtcDateTime.AddSeconds(10 * j);
Task delayedActivityCall = context
.CreateTimer(timeToStart, CancellationToken.None)
.ContinueWith(t => context.CallActivityAsync("PerformSubtask", j));
tasks.Add(delayedActivityCall);
}
await Task.WhenAll(tasks);
}
无论如何,这里是事件函数代码。
[FunctionName("PerformSubtask")]
public static void Activity([ActivityTrigger] int j, TraceWriter log)
{
log.Warning($"{DateTime.Now:o}: {j:00}");
}
从日志输出中,我看到所有事件调用彼此相隔 10 秒。
另一种方法是扇出到多个子编排(如 @jeffhollan 建议的),这些子编排是简单的持久计时器延迟和事件调用的短序列。
更新我尝试使用您更新的示例并能够重现您的问题!如果您在 Visual Studio 中本地运行并将异常设置配置为始终在发生异常时中断,那么您应该看到以下内容:
System.InvalidOperationException: 'Multithreaded execution was detected. This can happen if the orchestrator function code awaits on a task that was not created by a DurableOrchestrationContext method. More details can be found in this article https://learn.microsoft.com/en-us/azure/azure-functions/durable-functions-checkpointing-and-replay#orchestrator-code-constraints.'
这意味着调用 context.CallActivityAsync("PerformSubtask", j)
的线程与调用 Orchestrator 函数的线程不同。我不知道为什么我最初的例子没有达到这个目的,或者为什么你的版本没有达到这个目的。它与 TPL 如何决定使用哪个线程来运行您的 ContinueWith
委托(delegate)有关 - 我需要对此进行更多研究。
好消息是有一个简单的解决方法,即指定 TaskContinuationOptions.ExecuteSynchronously ,像这样:
Task delayedActivityCall = context
.CreateTimer(timeToStart, CancellationToken.None)
.ContinueWith(
t => context.CallActivityAsync("PerformSubtask", j),
TaskContinuationOptions.ExecuteSynchronously);
请尝试一下,并告诉我这是否可以解决您所观察到的问题。
理想情况下,使用 Task.ContinueWith
时不需要执行此解决方法。我在 GitHub 中打开了一个问题来跟踪此问题:https://github.com/Azure/azure-functions-durable-extension/issues/317
Since I do not want to collect the results of the activities I avoid calling
await Tasks.WhenAll(tasks)
after scheduling all activities. I do this in order to reduce the contention on the control queue i.e. be able to start another orchestration if reqd. Nevertheless the status of the 'orchestrator' is still 'Running' till all the activities finish running. I guess it moves to 'Complete' only after the last activity posts a 'done' message to the control queue.
这是预期的。在所有未完成的持久任务完成之前,Orchestrator 功能永远不会真正完成。没有任何办法可以解决这个问题。请注意,您仍然可以启动其他 Orchestrator 实例,只是如果它们碰巧落在同一分区上(默认情况下有 4 个分区),可能会出现一些争用。
关于c# - 仅在持久函数中扇出(并忘记),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50392874/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!