-1

我最近在用一些FileSystemWatchers 进行测试,想知道事件处理在 .NET 中是如何工作的。例如,在 VB.NET 中使用此代码:

Dim fsw1, fsw2, fsw3 As New FileSystemWatcher()

Private Sub fsw_Error(sender As Object, e As ErrorEventArgs) _
                                 Handles fsw1.Error, fsw2.Error, fsw3.Error
    Dim iCont As Integer = 1
    Dim fsw As FileSystemWatcher = CType(sender, FileSystemWatcher)

    While Not fsw.EnableRaisingEvents AndAlso iCont < 120
        iCont += 1

        Try
            fsw.EnableRaisingEvents = True
            txtResultado.Clear()
        Catch
            fsw.EnableRaisingEvents = False
            Threading.Thread.Sleep(30000)
        End Try
    End While
End Sub

每次在任何FileSystemWatchers 上发生错误时,都会执行该函数。为每个函数生成一个不同的线程FileSystemWatcher?它们可以在同时执行多个操作时相互干扰吗?

在这方面 C# 和 VB.NET 之间可能存在差异?

4

3 回答 3

1

哪个线程调用事件没有限制;如果您想在另一个线程中调用事件,您可以在 .NET 中自由地这样做。老实说,我无法想象不使用单独的线程或异步 IO 来实现 FileSystemWatcher (如果发现更改,则会调用事件),因为您不希望事件中断应用程序的正常流程。

.NET 中的事件使用一个调用列表,在引发事件时调用该列表。调用事件时,会遍历调用列表并在单个线程中调用每个方法。就那么简单。

该功能是 .NET 功能,因此 C# 和 VB.Net 相同

于 2013-02-13T09:14:02.107 回答
1

您对事件处理有一个基本的误解。似乎您假设所有触发的事件都将发送到同一个函数 - 或者可以说是函数的同一个实例

不是这种情况。每次引发事件时,都会调用函数 fsw_error。该函数是否已经执行了 10 次并不重要。因此,在该函数内部等待直到引发另一个事件(看起来您正在尝试这样做)是行不通的。

但是,您可以将事件处理程序封装在(实例化的)类中,并确保所有引发的事件执行都使用相同的变量范围。我不确定,如果事件是在不同的线程上触发的(不这么认为),但如果是这种情况,你当然需要注意同步访问。

Private Class MyEventHandlerHolder
   private iCont as Integer = 0;    

   Private Sub fsw_Error(sender As Object, e As ErrorEventArgs) _
                             Handles fsw1.Error, fsw2.Error, fsw3.Error

       iCont += 1

End Sub

每次文件系统观察程序触发错误事件时,iCont 都会增加。

fsw = new FileSystemWatcher()
fsw2 = new FileSystemWatcher()
fsw.EnableRaisingEvents = true;
fsw2.EnableRaisingEvents = true;
myHandler  = new MyEventHandlerHolder();
AddHandler fsw.Onerror, AdressOf myHandler.fsw_error //not sure about the right Event Name in vb
AddHandler fsw2.Onerror, AdressOf myHandler.fsw_error 

我的vb很久了。也许您不能将实例的方法定位为处理程序。但需要一个静态(或单例)处理程序类。

于 2013-02-13T09:17:45.087 回答
1

当 FileSystemWatchers 引发事件时,应在线程池线程上调用处理程序。这些事件可能会相互干扰,因为对一个 FileSystemWatcher 引发的事件的长时间处理可能会延迟对其中一个 FileSystemWatcher 引发的另一个事件的处理。在这种情况下,您可以在事件处理程序中使用专用线程来执行冗长的阻塞工作。

VB.NET 和 C# 之间应该没有区别。

于 2013-02-13T09:24:05.060 回答