英文:
Run dynamically added tasks one after one
问题
Application (wpf, .net framework 4.8) 可以从外部(rpc、ui 等)接收一些命令,而且可以接收得比可以执行得更快。在命令与硬件一起工作时,我希望它们按顺序执行。
我正在寻找想法,因为我甚至不确定我的计划是否能够奏效。
我目前的想法是以某种方式使用 Dataflow 中的 ActionBlock
,但我无法弄清楚如何正确编写它。
类似这样。
class Foo
{
ActionBlock<Task> runner;
int index = 0;
public async void TestTask(int index)
{
await Task.Delay(new Random().Next(1000, 10000));
Debug.WriteLine("Task completed " + index);
}
public Foo()
{
runner = new ActionBlock<Task>(async task =>
{
await task;
});
}
private async void button_Click(object sender, RoutedEventArgs e)
{
// 应该发布 TestTask(intex) 以延迟执行
runner.Post(() => TestTask(index));
index++;
}
}
也许有更好的方法来实现这个功能,或者一些聪明的架构来规避这些问题?
英文:
Application (wpf, .net framework 4.8) can receive some commands from outside (rpc, ui, etc) and can be received faster than can be executed. While commands work with hardware, I want them to be executed one by one.
I search for ideas, bc I do not even sure than my plan will work.
Me current idea is to somehow use ActionBlock
from Dataflow, but I can't figure out how to properly write it.
Something like this.
class Foo
{
ActionBlock<Task> runner;
int index = 0;
public async void TestTask(int index)
{
await Task.Delay(new Random().Next(1000, 10000));
Debug.WriteLine("Task completed " + index);
}
public Foo()
{
runner = new ActionBlock<Task>(task =>
{
task();
});
}
private async void button_Click(object sender, RoutedEventArgs e)
{
// should post TestTask(intex) for delayed execution
runner.Post(???);
index++;
}
}
May be there are better ways to achieve this functionality or some clever architecture to miss this problems?
答案1
得分: 2
以下是代码的翻译部分:
更简单的方法是只需传递一个异步委托类型,即 `Func<Task>`,然后使用闭包来创建委托实例:
```C#
ActionBlock<Func<Task>> runner;
public async Task TestTask(int index)
{
await Task.Delay(new Random().Next(1000, 10000));
Debug.WriteLine("任务完成 " + index);
}
public Foo()
{
runner = new ActionBlock<Func<Task>>(async func =>
{
await func();
});
}
private async void button_Click(object sender, RoutedEventArgs e)
{
var indexValue = index++;
runner.Post(() => TestTask(indexValue));
}
<details>
<summary>英文:</summary>
A simpler approach is to just pass in an asynchronous delegate type, i.e., `Func<Task>`, and use closures to create the delegate instances:
```C#
ActionBlock<Func<Task>> runner;
public async Task TestTask(int index)
{
await Task.Delay(new Random().Next(1000, 10000));
Debug.WriteLine("Task completed " + index);
}
public Foo()
{
runner = new ActionBlock<Func<Task>>(async func =>
{
await func();
});
}
private async void button_Click(object sender, RoutedEventArgs e)
{
var indexValue = index++;
runner.Post(() => TestTask(indexValue));
}
答案2
得分: -1
成功达到了我的期望。
大部分我的原始想法是正确的,只需要进行一些小修复。
以下是它们:
ActionBlock
应该接受委托和参数的元组ActionBlock
的操作应该是异步的,并等待任务
展示我最终结果的最小代码:
class Foo
{
delegate Task TaskDelegate(int book);
ActionBlock<Tuple<TaskDelegate, int>> runner;
int index = 0;
public async Task TestTask(int index)
{
await Task.Delay(new Random().Next(1000, 10000));
Debug.WriteLine("Task completed " + index);
}
public Foo()
{
runner = new ActionBlock<Tuple<TaskDelegate, int>>(async task =>
{
await task.Item1(task.Item2);
});
}
private async void button_Click(object sender, RoutedEventArgs e)
{
runner.Post(Tuple.Create<TaskDelegate, int>(TestTask, index));
index++;
}
}
英文:
Managed to achieve what I expect.
Mostly my original idea was right, only minor fixes was needed.
Here they are:
ActionBlock
should accept tuple of deletage and parametersActionBlock
's actoin should be async and await for task
Minimal code to show my final result:
class Foo
{
delegate Task TaskDelegate(int book);
ActionBlock<Tuple<TaskDelegate, int>> runner;
int index = 0;
public async Task TestTask(int index)
{
await Task.Delay(new Random().Next(1000, 10000));
Debug.WriteLine("Task completed " + index);
}
public Foo()
{
runner = new ActionBlock<Tuple<TaskDelegate, int>>(async task =>
{
await task.Item1(task.Item2);
});
}
private async void button_Click(object sender, RoutedEventArgs e)
{
runner.Post(Tuple.Create<TaskDelegate, int>(TestTask, index));
index++;
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论