gpt4 book ai didi

c# - ExcelAsyncUtil.Observe - 在 Excel 中创建运行时钟

转载 作者:行者123 更新时间:2023-12-02 01:37:41 26 4
gpt4 key购买 nike

我正在尝试 ExcelAsyncUtil.Observe 函数。我编写了以下代码,在 Excel 中显示正在运行的时钟。它工作正常,但我不确定我在做什么。两个问题:

  1. 我应该为observer.OnCompleted() 和observer.OnError() 添加功能吗?这些调用有什么作用?
  2. 我应该在 IDisposible 类中做什么?为什么会在那里?

这是我的示例代码:

    [ExcelFunction]
public static object MyExcelTicker()
{
return ExcelAsyncUtil.Observe("MyExcelTicker", new object[] { }, TickerFunction());
}

public static ExcelObservableSource TickerFunction()
{
ExcelObservableSource source = new ExcelObservableSource(() => new TickerObservable());
return source;
}

public class TickerObservable : IExcelObservable
{
public IDisposable Subscribe(IExcelObserver observer)
{
var timer = new System.Timers.Timer();
timer.Interval = 1000;
timer.Elapsed += (s, e) => observer.OnNext(DateTime.Now.ToString());
timer.Start();

// What about observer.OnCompleted() and observer.OnError()?
return new TickerDisposable();
}
}

public class TickerDisposable : IDisposable
{
public void Dispose()
{
// What to do here?
}
}

最佳答案

已经有一段时间了,至少还有一件事没有被提及,所以让我补充一下戈弗特所说的内容。

您问过:

public class TickerDisposable : IDisposable
{
public void Dispose()
{
// What to do here?
}
}

让我们总结一下:

对于时钟自动收录器的每个新订阅者,将在 TickerObservable 上调用 Subscribe。因此,对于每个订阅者,您的代码将创建一个新的 System.Timers.Timer 和一个新的 timer.Elapsed 事件处理程序 - 以达到您预期的效果。这实际上就是获得效果所需的全部内容。

但是,您还需要返回 IDisposable,因此您仅出于此目的创建了一个虚拟 TickerDisposable,并且您不确定它的用途。

答案:

图书馆要求您从订阅返回的 IDisposable 只是为了让您在闪光停止发光后进行清理。计时器是一个“系统事物”。一旦您创建并启动它们,它们就会运行。一小时后,它们将无法被 GC 处理,因为它们将运行,直到您停止它们为止。当然,您已经+='ed了一个事件处理程序,观察者(如果弱引用)可能已经死了,但您的计时器不知道!你必须在某个时刻停止它。

因此,借用自 RX 的 IDisposable 相关模式:无论您在 Subscribe 方法中分配、保留、构建等重或长期存在的内容,都将一些有关它的注释放入(您的!)IDisposable 中。然后,当观察者取消订阅时,您的 IDisposable 也将被清理,并且您的自定义 Dispose 方法将运行,它将能够查看您的 IDiposable 的内容并..清理垃圾,或者更确切地说, 解锁它,以便 GC 可以刷新它们。

完成您的示例:

public class TickerObservable : IExcelObservable
{
public IDisposable Subscribe(IExcelObserver observer)
{
var timer = new System.Timers.Timer();
timer.Interval = 1000;
timer.Elapsed += (s, e) => observer.OnNext(DateTime.Now.ToString());
timer.Start();

return new TickerDisposable(timer);
}
}

public class TickerDisposable : IDisposable
{
private Timer ticky;
public TickerDisposable(Timer timer)
{
ticky = timer;
}

public void Dispose()
{
if(ticky != null)
ticky.Dispose(); // or Stop, or etc..
}
}

上面的示例实际上是返回的 IDisposable 最明显的用法。但是,您可以将其用于任何注册-取消注册通知。例如,对于单个共享计时器,它可能如下所示:

public class TickerObservable : IExcelObservable
{
private static Timer timer = ..... ; // assume it is up & running & shared

public IDisposable Subscribe(IExcelObserver observer)
{
ElapsedEventHander hd = (s, e) => observer.OnNext(DateTime.Now.ToString());
timer.Elapsed += hd;

return new TickerDisposable(timer, hd);
}
}

public class TickerDisposable : IDisposable
{
private Timer ticky;
private ElapsedEventHander handler;

public TickerDisposable(Timer timer, ElapsedEventHander hd)
{
ticky = timer;
handler = hd;
}

public void Dispose()
{
if(ticky != null && handler != null)
ticky.Elapsed -= handler;
}
}

现在你完全确定没有死亡处理程序在长生命周期共享计时器上徘徊。 (当然,这里缺少计时器的清理,但那是另一回事......)。也许您已经有了这个想法,所以,玩得开心!

关于c# - ExcelAsyncUtil.Observe - 在 Excel 中创建运行时钟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18026991/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com