事件处理程序似乎创建了新的线程

本文关键字:线程 创建 程序 事件处理 | 更新日期: 2023-09-27 18:19:47

我正在使用FileSystemWatcher类,注意到创建的事件的事件处理程序在一个单独的线程上运行。我正在努力理解多线程编程,我的印象是,你唯一免费获得的线程是主线程。

我想,当你想拥有另一个线程时,你需要显式地创建它。我很困惑为什么事件处理程序方法中的代码在不同于主线程的线程中运行。

class Program
{
    static void Main(string[] args)
    {
        FileSystemWatcher w = new FileSystemWatcher(@"c:'test'");       
        w.Created += new FileSystemEventHandler(OnCreated);
        w.EnableRaisingEvents = true;
        Console.ReadLine();
    }

    private static void OnCreated(object source, FileSystemEventArgs e)
    {
        // Specify what is done when a file is changed, created, or deleted.
       Console.WriteLine("File: " +  e.FullPath + " " + e.ChangeType + " " + Thread.CurrentThread.ManagedThreadId);
    }
}

我希望有人能为我澄清这一点。谢谢

事件处理程序似乎创建了新的线程

你被误解了。系统中只有显式创建的线程才是,而不是。您可以使用其他API或库(包括Java附带的"核心"库),这些库可以自由创建所需的任何线程,以便实现和提供所宣传的服务。在许多情况下,除了创建自己的线程之外,没有其他方法。

一些例子:

  1. 您正在使用的文件观察程序服务。某些东西需要与操作系统交互,并检测文件系统中的某些东西是否发生了更改。监视和回调异步地发生在主线程上(也就是说,并行地发生,而不与的定时绑定)
  2. Swing(GUI)。这必须在另一个线程上运行,这样即使其他线程(如主线程)正在做其他事情,UI也可以工作(并保持响应)
  3. 垃圾收集器线程在后台运行,并定期回收要重用的内存
  4. 等等

编辑:

为了回答您关于如何知道api何时将使用自己的线程进行回调的问题:

  1. 查看文档。对于核心等高质量的apiapi,这类事情经常被记录下来
  2. 根据一般经验,您可以假设任何进行回调的api都会使用自己的线程来进行回调(通常但并不总是这样)
  3. 试着学习(或预测,或猜测)图书馆内部是如何运作的。再一次,文档是一个很好的起点。如果你了解到它有自己的线程,如果它进行回调,那么这些回调很可能会发生在这些线程上
  4. 运用一些常识。除非您首先调用api,否则api不能使用您的(主线程或其他线程)对您进行回调。为了在任意的一段时间内工作,api需要在这段时间内独占你的线程,这意味着你将无法将线程用于其他任何事情