c# - 如何在 C# 中的 GUI 线程上启动一系列定时事件?

标签 c# asynchronous f# task-parallel-library system.reactive

我有一个应用程序必须执行以下类型的操作,最好是在 GUI 线程上,因为这是大多数操作发生的地方,并且没有长时间运行的操作:

Wait 1000
FuncA()
Wait 2000
FuncB()
Wait 1000
FuncC()

我意识到我可以使用带有状态机样式 OnTick 函数的计时器,但这看起来很麻烦:

    int _state;
    void OnTick(object sender, EventArgs e) {
        switch (_state) {
            case 0:
                FuncA();
                _timer.Interval = TimeSpan.FromSeconds(2);
                _state = 1;
                break;
            case 1:
                FuncB();
                _timer.Interval = TimeSpan.FromSeconds(1);
                _state = 2;
                break;
            case 2:
                FuncC();
                _timer.IsEnabled = false;
                _state = 0;
        }
    }

另外,我希望能够使其足够通用以执行类似的操作

RunSequenceOnGuiThread(new Sequence {
    {1000, FuncA}
    {2000, FuncB}
    {1000, FuncC}};

有没有一种惯用的方法来做这种事情?考虑到所有 TPL 内容,或 Rx,甚至 F# 中的计算表达式,我假设存在一个,但我没有找到它。

最佳答案

Observable.Concat(
        Observer.Timer(1000).Select(_ => Func1()),
        Observer.Timer(2000).Select(_ => Func2()),
        Observer.Timer(1000).Select(_ => Func3()))
    .Repeat()
    .Subscribe();

要使这项工作有效,您唯一需要做的就是确保您的 Func 返回一个值(即使该值是 Unit.Default,即什么都没有)

编辑:以下是制作通用版本的方法:

IObservable<Unit> CreateRepeatingTimerSequence(IEnumerable<Tuple<int, Func<Unit>>> actions)
{
    return Observable.Concat(
        actions.Select(x => 
            Observable.Timer(x.Item1).Select(_ => x.Item2())))
        .Repeat();
}

关于c# - 如何在 C# 中的 GUI 线程上启动一系列定时事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9845257/

相关文章:

c# - Nunit ExpectedException 是否正常工作?

c# - 在 C# 中使文件可写的最佳方法

javascript - 如何在 JavaScript 中模拟数据库限制?

java - Spring异步文件上传

c# - 无法将类型 'System.Threading.Tasks.Task' 隐式转换为 'Windows.Foundation.IAsyncAction' 。存在显式转换

parsing - 使 OperatorPrecedenceParser 解析 Optional (opt) 表达式

c# - 如何在属性中使用查询参数?

c# - Entity Framework 的表连接性能问题

.net - 尝试在 Linux 上将 Mpir.NET 与 F# 一起使用

linq-to-sql - 向 Linq-To-Sql 数据提供程序提供连接字符串