4

我正在开发 c# windows 服务,它将监视多个文件、文件夹和数据库表的任何更改。观察者分为三种类型(我称它们为观察者)。

  1. FileWatcher :使用 .Net FileSystemWatcher持续监视文件并引发要发送警报的事件。发送警报后,手表功能恢复。

  2. FolderWatcher:使用 .Net Timer持续监视文件夹并引发在特定条件下发送警报的事件。发送警报后,手表功能恢复。

  3. DBWatcher:每分钟(定时器)执行一次 SQL 查询,如果结果错误则发送警报。

你可以猜到,这些所有的观察者都会一直运行在 windows 服务运行的地方。

它们都实现了一个接口IWatcher并提供了一个BeginWatch方法,该方法执行每个 watcher 所需的操作,例如使用 timer 每分钟查询一次 DB(如果 watcher 是 DBWatcher)。创建这些观察者的输入是一个 XML 文件。它包含如下内容:

<?xml version="1.0" encoding="utf-8"?>
<watchlist>

    <watcher type="FolderWatcher">
        <path>D:\Projects\.Net\V1\</path>
        <PauseInMinBtwAlerts>1</PauseInMinBtwAlerts>
        <alert>xxx@xxx.com</alert>
    </watcher>

    <watcher type="FileWatcher">
        <path>D:\Projects\.Net\</path>
        <fileName>e.txt</fileName>
        <alert>yyy@yyy.com</alert>
    </watcher>

    <watcher type="DBWatcher">
        <sqlquery>select blah blah blah ... </sqlquery>
        <connectionstring>connection string for the DB</connectionstring>
        <alert>yyy@yyy.com</alert>
    </watcher>

</watchlist>

这个 XML 告诉我们要创建多少个观察者。可以创建数十个观察者。

由于我们面临的一些问题,我们决定每个观察者将在不同的线程上运行。因此,如果出现未处理的异常,只能停止/终止该线程,我们会通过电子邮件警报通知 IT 部门有关情况。我们必须能够在以后恢复它。

现在我很困惑。因为有线程、异步任务、池线程、后台线程等。我应该使用什么???/我是这个线程的新手。

让我告诉您我的要求,然后您可以指导我找到一些适当的解决方案:

  1. 我希望每个观察者都在单独的线程中运行。
  2. 线程必须连续运行,并且我的观察者必须能够观察到 Windows 服务本身关闭。
  3. 线程必须能够与其父线程(创建每个线程的类)通信以更新其状态。
  4. 线程中任何未处理的异常都必须在线程本身中捕获,然后传递给父类(使用第 3 点)。

我创建了以下类,它将负责创建、通信和管理所有线程:

public class WatcherThreadsManager
{
    //This will keep list of all active threads ... as I will be communicating with them later
    private List<Thread> _watcherThreads;

    public WatcherThreadsManager()
    {
        this._watcherThreads = new List<Thread>();
    }

    //I will call this method and pass in any watcher which i want to run in a new thread
    public void CreateWatcherThread(IWatcher watcher)
    {
        Thread _watcher = new Thread(_createWatcherThread);

        //the Copy() will produce its deeply copied copy ... i wanted to make sure thread works on a free object .. not sure
        _watcher.Start(watcher.Copy());

        //Add Thread to threads' list
        this._watcherThreads.Add(_watcher);
    }

    private void _createWatcherThread(object wat)
    {
        IWatcher watcher = wat as IWatcher;
        try
        {
            //the following function will begin the watch.
            //I dont want any loop either .. as i want to call the BeginWatch() method only once.
            watcher.BeginWatch();
        }
        catch (Exception ex)
        {
            // i should be able to inform the parent thread about the exception so this thread is set to sleep. as we can reactivate it later when the issue fixes.
            // how to do that?
        }
    }
} 

实现我想要的最好方法是什么?

4

2 回答 2

4

您可以通过使用任务来满足您的所有要求,这里有几个链接供进一步阅读:

  1. 创建线程 - Task.Factory.StartNew vs new Thread()

  2. 最佳实践 LongRunning 任务创建

  3. 任务报告进度

  4. 处理任务异常

祝你好运!

于 2013-05-03T15:00:59.473 回答
1

由于我们面临的一些问题,我们决定每个观察者将在不同的线程上运行。因此,如果出现未处理的异常,则只能停止/杀死该线程

这听起来像你不需要线程,你需要捕捉你的异常。你为什么不这样做?

于 2013-05-03T15:24:46.137 回答