Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/google-sheets/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 可以为Windows服务工作人员使用任务吗_.net_Service_Task Parallel Library - Fatal编程技术网

.net 可以为Windows服务工作人员使用任务吗

.net 可以为Windows服务工作人员使用任务吗,.net,service,task-parallel-library,.net,Service,Task Parallel Library,在Windows服务中为工作线程使用任务是一个好的设计,还是我们最好坚持使用Thread.Start()?如果工作进程大部分处于空闲状态,或者被FileSystemWatcher事件触发,或者使用Take()off BlockingCollections进行处理,那么甚至可能不会启动长时间运行的工作进程 Public Class FileWatcherService Private _watchPaths As New List(Of String) From {"x:\Dir1","x:\Di

在Windows服务中为工作线程使用任务是一个好的设计,还是我们最好坚持使用Thread.Start()?如果工作进程大部分处于空闲状态,或者被FileSystemWatcher事件触发,或者使用Take()off BlockingCollections进行处理,那么甚至可能不会启动长时间运行的工作进程

Public Class FileWatcherService
Private _watchPaths As New List(Of String) From {"x:\Dir1","x:\Dir2","y:\Dir1", ...}
Private _workers As New List(Of Task)
Private _cancellationTokenSource As New CancellationTokenSource()
Private _cancellationToken As CancellationToken = _cancellationTokenSource.Token

Protected Overrides Sub OnStart(ByVal args() As String)
    For Each path In _watchPaths
        _workers.Add(
            Task.Factory.StartNew(
                Sub()
                    Dim fileProcessor As New FileProcessor
                    fileProcessor.StartWorking(path, _cancellationToken)
                End Sub, TaskCreationOptions.LongRunning, _cancellationToken))
    Next
End Sub

Protected Overrides Sub OnStop()
    _cancellationTokenSource.Cancel()
    Task.WaitAll(_workers.ToArray)
End Sub
End Class

Class FileProcessor
Private _newFiles As New BlockingCollection(Of String)
Sub _fileWatcher_Created(sender As Object, e As FileSystemEventArgs)
    _newFiles.Add(e.FullPath, _cancellationToken)
End Sub

Async Function ProcessNewFiles() As Task
    Do
        Await ProcessFile(_newFiles.Take(_cancellationToken))
    Loop
End Function
End Class
编辑

上述方法不会在空闲时释放工作线程,因为Take()上的阻塞。 以下解决方案使用ActionBlock而不是BlockingCollection。此解决方案在空闲地监视新文件时不会使用线程。我启动线程来处理新文件,并在完成后释放它们。我不再使用LongRunning启动顶级worker任务

Class FileProcessor
Private _newFilesActionBlock As New ActionBlock(Of String)(
    Async Function(filePath)
        Await ProcessFile(filePath)
    End Function,
        New ExecutionDataflowBlockOptions With {
            .CancellationToken = _cancellationToken})

Sub _fileWatcher_Created(sender As Object, e As FileSystemEventArgs)
                        Handles __fileWatcher.Created
    _newFilesActionBlock.Post(e.FullPath)
End Sub
'...

终端类

TPL是一个非常受欢迎的.NET框架的添加。它使线程代码更易于使用,可读性更强。它允许您使您的windows服务(或任何其他线程代码)成为多线程,而无需实例化和处理线程池和单个线程

我在我的windows服务中使用TPL,它对我非常有用,我非常推荐在大多数情况下使用TPL而不是经典的线程池


也就是说,在一些非常罕见的情况下,您仍然希望自己处理线程池,但根据您的代码片段,您似乎不需要为此费心……

我特别感兴趣的是如何最好地创建这些顶级工作线程(示例代码中的fileProcessor)。他们中可能有百分之一百的人,每个人都永远活着,有些人大部分时间都在闲着。如果我们将它们创建为LongRunning,它们将获得专用线程(使用当前的TPL实现,将来可能会发生变化)。如果我们在没有长时间运行的情况下创建它们,那么它们是在线程池上创建的,在空闲时不会消耗线程。与专用工作线程相比,这种方法有意义吗?有关此问题的更深入讨论[MSDN论坛]()