C# 卷更改事件-在卷停止更改时侦听

C# 卷更改事件-在卷停止更改时侦听,c#,listener,volume,C#,Listener,Volume,我的服务器正在使用第三方库控制windows卷。 当服务器从客户端收到一条消息,告诉它更改卷时,它正在做它需要做的事情,没有任何问题。但是,每当计算机上的卷在本地发生更改时,我都要通知客户机 我正在使用的这个图书馆(https://workspaces.codeproject.com/ray-m/vista-core-audio-api-master-volume-control/article),具有通知卷更改的事件 问题是,它会通知每个小的音量更改步骤,因此当用户更改音量时,代理会被多次调用

我的服务器正在使用第三方库控制windows卷。 当服务器从客户端收到一条消息,告诉它更改卷时,它正在做它需要做的事情,没有任何问题。但是,每当计算机上的卷在本地发生更改时,我都要通知客户机

我正在使用的这个图书馆(https://workspaces.codeproject.com/ray-m/vista-core-audio-api-master-volume-control/article),具有通知卷更改的事件

问题是,它会通知每个小的音量更改步骤,因此当用户更改音量时,代理会被多次调用。例如:

如果当前音量为-23db,并且用户将音量调到-13db,那么将调用代理10次

我如何监听用户何时开始更改音量,以及何时结束操作

这样,我将能够通过委托只向客户端发送一次更新

已尝试的代码:

void AudioEndpointVolume_OnVolumeNotification(AudioVolumeNotificationData data)
{

    VolumeTimer.Interval = 300;
    VolumeTimer.Stop();
    VolumeTimer.Start();

}

private void VolumeTimer_Tick(object sender, EventArgs e)
{
    VolumeTimer.Stop();

    lock (_lock)
    {
        ++_volumeCalledCounter;

        if (_volumeCalledCounter <= 1)
        {
            Console.WriteLine("Fired");
            _volumeCalledCounter = 0;
        }
    }

}
void AudioEndpointVolume\u OnVolumeNotification(AudioVolumeNotificationData数据)
{
容积计间隔=300;
VolumeTimer.Stop();
VolumeTimer.Start();
}
私有void VolumeTimer_Tick(对象发送方,事件参数e)
{
VolumeTimer.Stop();
锁
{
++_容量计数器;

如果(\u volumeCalledCounter是的,
计时器可以重复启动。因此,每次收到volumeChange通知时,您都应该停止
并启动
计时器。虽然这些计时器的启动速度比
计时器快。间隔
不会发生任何其他情况。一旦计时器停止运行,则
计时器.勾号
将最终启动。这里您最后一次停止
计时器
并触发您自己的事件

使用
定时器音量调节器和原始来源:

defaultDevice.AudioEndpointVolume.OnVolumeNotification += new 
    AudioEndpointVolumeNotificationDelegate(
       AudioEndpointVolume_OnVolumeNotification);


void AudioEndpointVolume_OnVolumeNotification(AudioVolumeNotificationData data)
{
   VolumeTimer.Interval = 100;  // ms, test to gauge!
   VolumeTimer.Stop();
   VolumeTimer.Start();
}

private void VolumeTimer_Tick(object sender, EventArgs e)
{
   VolumeTimer.Stop();
   // whatever you want to do, when the volume no longer changes:
   yourEvent();         
}
编辑:

上面的代码应该可以解决原来的问题

但是,如果用户缓慢地更改卷,但更改时间过长,则不会一直触发事件。如果您要强制执行UI更新,则使用第二个
计时器VolumeUtimer
,可以执行一点额外的代码:

void AudioEndpointVolume_OnVolumeNotification(AudioVolumeNotificationData data)
{
   VolumeTimer.Interval = 100;  // ms, test to gauge!
   VolumeTimer.Stop();
   VolumeTimer.Start();
   if (!VolumeUiTimer.Enabled) 
      { VolumeUiTimer.Interval = 500; VolumeUiTimer.Start();
}

private void VolumeTimer_Tick(object sender, EventArgs e)
{  // no more changes: all timers stop, update UI
   VolumeTimer.Stop();
   VolumeUiTimer.Stop();
   // whatever you want to do, when the volume no longer changes:
   yourEvent();         
}

private void VolumeUiTimer_Tick(object sender, EventArgs e)
{  //restart timer1, stop timer2, update UI 
   VolumeTimer.Stop();
   VolumeTimer.Start();
   VolumeUiTimer.Stop();
   // whatever you want to do, when the volume no longer changes:
   yourEvent();         
}
我在这里设置
间隔
只是为了演示;它们可以在
InitializeComponent()之后移动,也可以简单地移动到设计器中


搁置在多个
计时器上
:有一段时间,应用程序可以创建的
计时器的数量被限制在16个。这已经过去很久了,创建第二个
计时器

没有问题。每次启动/重新启动计时器。当它勾选时,卷更改完成。测试以找到一个好的方法间隔,500毫秒可以工作。你能给我一些例子吗?据我所知,计时器会在指定的间隔自动触发事件。我想“吸收”一些事件,然后只触发一个事件。谢谢你看起来很有趣,我会很快测试它。@Yosi199:看我的扩展答案!我已经实现了你的示例(不需要第二个计时器,因为我只想在停止更改音量时触发事件,至少现在是这样)但是由于某些原因,我仍然会被触发两次事件!我会在我的PostMay中发布我的代码实现,可能是一个bug或其他原因,因为它现在工作得很好-一次只触发一个事件哈,谢谢你让我知道!!我对此感到困惑-为了测试我已经挂上了鼠标Move不知道这个事件是意外的我很狡猾,即使没有移动鼠标,也会无缘无故地开火,这让我挠头……-)