首页 \ 问答 \ WPF后台工作者和ProgressBar(WPF Background Worker and ProgressBar)

WPF后台工作者和ProgressBar(WPF Background Worker and ProgressBar)

所以,我有一个wpf表单,它发送到一个站点,解析html,并返回一个强类型的'href'值列表。 (是的,这是我自己的网站)

我正在利用backgroundworker来释放UI的挂断,并呈现正在运行的进度条。

虽然它只对网站的第一页很有效,但如果我决定递归网站,进度条会挂起,而递归就会发生,那么一旦递归完成,进度条就会恢复生机。

你能告诉我这里我做错了什么吗? 并且可以指导我使用进度条正确使用所述后台工作程序...基本上,进度条应该在执行任务时运行,但我假设基于代码,这确实不是这种情况。

以下是完成此操作的窗口的代码隐藏:

Imports System.Threading.Tasks
Imports System.Threading

Class MainWindow

Private _previousCursor As Cursor = Mouse.OverrideCursor
Private _Spider As New Spider.SpiderIt
Private _Worker As New ComponentModel.BackgroundWorker
Private _RunCount As Integer = 0

Private Sub MainWindow_Loaded(sender As Object, e As System.Windows.RoutedEventArgs) Handles Me.Loaded
    Me.workProgress.Visibility = Windows.Visibility.Hidden
    _Worker.WorkerReportsProgress = True
    _Worker.WorkerSupportsCancellation = True
    AddHandler _Worker.DoWork, New System.ComponentModel.DoWorkEventHandler(AddressOf Spider)
    AddHandler _Worker.ProgressChanged, New System.ComponentModel.ProgressChangedEventHandler(AddressOf worker_ProgressChanged)
    AddHandler _Worker.RunWorkerCompleted, New System.ComponentModel.RunWorkerCompletedEventHandler(AddressOf worker_RunWorkerCompleted)
    Me.SiteParse.Focus()
End Sub

Private Sub SiteParseKeyDown(sender As System.Object, e As System.Windows.Input.KeyEventArgs)
    If (e.Key = Key.Return) Then
        Me.btnParseAll.IsEnabled = False
        Me.btnParseSelected.IsEnabled = False
        Me.SiteParse.IsEnabled = False
        Mouse.OverrideCursor = Cursors.Wait
        Me.workProgress.Visibility = Windows.Visibility.Visible
        _Worker.RunWorkerAsync(New Typing() With {.Url = SiteParse.Text, .Recurse = Recurse.IsChecked})
    End If
End Sub

Private Sub btnParseAll_Click(sender As Object, e As System.Windows.RoutedEventArgs) Handles btnParseAll.Click
    Me.btnParseAll.IsEnabled = False
    Me.btnParseSelected.IsEnabled = False
    Me.SiteParse.IsEnabled = False
    Dim _TL As New List(Of DGTyping)
    Using New WaitCursor
        For Each Item In DG_SiteLinks.Items
            _TL.Add(New DGTyping() With {
                    .SiteUrl = Item.SiteUrl,
                    .SiteTitle = Item.SiteTitle
                })
        Next
    End Using
    Dim _T As New ParseLinks(Me, _TL)
    _T.ShowDialog()
End Sub

Private Sub btnParseSelected_Click(sender As Object, e As System.Windows.RoutedEventArgs) Handles btnParseSelected.Click
    Me.btnParseAll.IsEnabled = False
    Me.btnParseSelected.IsEnabled = False
    Me.SiteParse.IsEnabled = False
    Dim _TL As New List(Of DGTyping)
    Using New WaitCursor
        For Each Item In DG_SiteLinks.SelectedItems
            _TL.Add(New DGTyping() With {
                    .SiteUrl = Item.SiteUrl,
                    .SiteTitle = Item.SiteTitle
                })
        Next
    End Using
    Dim _T As New ParseLinks(Me, _TL)
    _T.ShowDialog()
End Sub

#Region "Get Site Links"

Private Sub Spider(sender As Object, e As System.ComponentModel.DoWorkEventArgs)
    'Do the work here, but need to get the value of SiteParse first
    With _Spider
        .UrlToParse = DirectCast(e.Argument.Url, String)
        .ShouldRecurse = DirectCast(e.Argument.Recurse, Boolean)
        .RecurseLevels = 20
        .SpiderIt(_Worker)
    End With
End Sub

Private Sub worker_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs)
    workProgress.Value = e.ProgressPercentage
End Sub

Private Sub worker_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs)
    EndRest()
    Dim _IL As List(Of Spider.Typing.InternalLinks)
    _IL = _Spider.InternalLinks()
    Dim _TL As New List(Of DGTyping)
    For Each item In _IL
        _TL.Add(New DGTyping() With {
                .SiteUrl = item.Url,
                .SiteTitle = If(item.Title.Length > 0, item.Title, item.Content)
            })
    Next
    _IL.Clear()
    Me.DG_SiteLinks.ItemsSource = _TL
    EndSync()
End Sub

Private Sub BrowseSite(sender As Object, e As RoutedEventArgs)
    Dim _URL As String = DirectCast(sender, TextBlock).Text
    Dim _T As New Browser(_URL)
    _T.ShowDialog()
End Sub

Private Sub Window_Closing(sender As Object, e As System.ComponentModel.CancelEventArgs)
    If _Worker IsNot Nothing Then
        If _Worker.IsBusy Then
            _Worker.CancelAsync()
        End If
    End If
End Sub

Private Sub EndSync()
    _Worker.CancelAsync()
    _Worker.Dispose()
    _Spider.Dispose()
End Sub

Private Sub EndRest()
    workProgress.Value = 0
    workProgress.Visibility = Windows.Visibility.Hidden
    Me.btnParseAll.IsEnabled = True
    Me.btnParseSelected.IsEnabled = True
    Me.SiteParse.IsEnabled = True
    Mouse.OverrideCursor = _previousCursor
End Sub

Partial Public Class Typing
    Public Property Url As String
    Public Property Recurse As Boolean
End Class

Partial Public Class DGTyping
    Public Property SiteUrl As String
    Public Property SiteTitle As String
End Class

#End Region

End Class

.SpiderIt()走出指定的站点,将html抓取为HDocument(SuperstarCoders LinqToHtml),解析内部链接,并将它们抛出到强类型列表中。 这是在一个单独的类组件中完成的,并且表现完美。

SpiderIt方法和包含类:

Imports Superstar.Html.Linq
Imports System.Threading.Tasks

Public Class SpiderIt
Implements IDisposable

#Region "Public Properties"

''' <summary>
''' Specify the initial URL to parse
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public Property UrlToParse As String

''' <summary>
''' Should this recurse the internal links of the site
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public Property ShouldRecurse As Boolean = False

''' <summary>
''' Specify the number of levels to recurse
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public Property RecurseLevels As Long = 0

''' <summary>
''' Returns a message from the SpiderIt method
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public ReadOnly Property Message() As String
    Get
        Return _Msg
    End Get
End Property

''' <summary>
''' Returns a strongly typed list of internal links
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public ReadOnly Property InternalLinks() As List(Of Typing.InternalLinks)
    Get
        Return _InternalLinkList
    End Get
End Property

''' <summary>
''' Returns a strongly typed list of external links
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public ReadOnly Property ExternalLinks() As List(Of Typing.ExternalLinks)
    Get
        Return _ExternalLinkList
    End Get
End Property

#End Region

#Region "Internal Properties"

Private disposedValue As Boolean
Private _Msg As String
Private _Ctr As Long = 0
Private _InternalLinkList As New List(Of Typing.InternalLinks)
Private _ExternalLinkList As New List(Of Typing.ExternalLinks)
Private _DLer As New Downloader
Private _RCt As Long = 0

#End Region

#Region "Public Methods"

''' <summary>
''' Parse with the specified values
''' </summary>
''' <returns>Boolean</returns>
''' <remarks>Returns true or false, based on if it has completed, as well as a message
''' Spits out 2 strongly typed lists.  Both internal and external URLs
''' </remarks>
Public Function SpiderIt(ByVal _Worker) As Boolean
    For i As Integer = 1 To 99
        _Worker.ReportProgress(i)
        System.Threading.Thread.Sleep(50)
    Next
    _Worker.ReportProgress(100)
    Dim _Doc As HDocument = _DLer.DownloadHDoc(UrlToParse)
    With _Doc
        If _Doc Is Nothing Then
            _Msg = "There is no document to parse."
            Return False
        Else
            Try
                Dim _AL = .Descendants("a")
                'Parse the internal links
                ParseLinks(_AL)
                _Msg = "Internal Link List Built"
                Return True
            Catch ex As Exception
                _Msg = ex.Message
                Return False
            End Try
        End If
    End With
End Function

#End Region

#Region "Internal Methods"

#Region "Spider Helpers"

Private Sub ParseLinks(ByVal _AL As IEnumerable(Of HElement))
    Try
        Dim _Link As String, _D As HDocument
        For i As Long = 0 To _AL.Count - 1
            If _AL(i).Attribute("href") IsNot Nothing AndAlso Not (_AL(i).Attribute("href").Value.Contains("//") OrElse
                    _AL(i).Attribute("href").Value.Contains("http://") OrElse
                    _AL(i).Attribute("href").Value.Contains("https://") OrElse
                    _AL(i).Attribute("href").Value.Contains("ftp://") OrElse
                    _AL(i).Attribute("href").Value.Contains("mailto:") OrElse
                    _AL(i).Attribute("href").Value.Contains("#")) Then
                _Link = UrlToParse & "/" & _AL(i).Attribute("href").Value
                If Not (_InternalLinkList.Any(Function(x) x.Url = _Link.Replace("//", "/").Replace("http:/", "http://").Replace("https:/", "https://"))) Then
                    AddInternalLinks(_Link.Replace("//", "/").Replace("http:/", "http://").Replace("https:/", "https://"),
                                     If(_AL(i).Attribute("target") Is Nothing,
                                         String.Empty,
                                         _AL(i).Attribute("target").Value),
                                     _AL(i).Value,
                                     If(_AL(i).Attribute("title") Is Nothing,
                                         String.Empty,
                                         _AL(i).Attribute("title").Value))
                    If ShouldRecurse Then
                        _RCt += 1
                        If _RCt <= RecurseLevels Then
                            _D = _DLer.DownloadHDoc(_Link)
                            ParseLinks(_D.Descendants("a"))
                        End If
                    End If
                End If
            Else
                _Link = _AL(i).Attribute("href").Value
                If Not (_ExternalLinkList.Any(Function(x) x.Url = _Link)) Then
                    AddExternalLinks(_Link,
                                     If(_AL(i).Attribute("target") Is Nothing,
                                         String.Empty,
                                         _AL(i).Attribute("target").Value),
                                     _AL(i).Value,
                                     If(_AL(i).Attribute("title") Is Nothing,
                                         String.Empty,
                                         _AL(i).Attribute("title").Value))
                End If
            End If
        Next
    Catch ex As Exception
        _Msg += ex.StackTrace
    End Try
End Sub

Private Sub AddExternalLinks(ByVal _Link As String, ByVal _Target As String, ByVal _Content As String, ByVal _Title As String)
    Try
        _ExternalLinkList.Add(New Typing.ExternalLinks With {
                            .Url = _Link,
                            .Content = _Content,
                            .Target = _Target,
                            .Title = _Title
                        })
    Catch ex As Exception
        _Msg += ex.StackTrace
    End Try
End Sub

Private Sub AddInternalLinks(ByVal _Link As String, ByVal _Target As String, ByVal _Content As String, ByVal _Title As String)
    Try
        _InternalLinkList.Add(New Typing.InternalLinks With {
                            .Url = _Link,
                            .Content = _Content,
                            .Target = _Target,
                            .Title = _Title
                        })
    Catch ex As Exception
        _Msg += ex.StackTrace
    End Try
End Sub

#End Region

#Region "IDisposable Support"

Protected Overridable Sub Dispose(disposing As Boolean)
    If Not Me.disposedValue Then
        If disposing Then
        End If
        _Msg = String.Empty
        _InternalLinkList.Clear()
        _ExternalLinkList.Clear()
        _DLer.Dispose()
    End If
    Me.disposedValue = True
End Sub

Public Sub Dispose() Implements IDisposable.Dispose
    Dispose(True)
    GC.SuppressFinalize(Me)
End Sub

#End Region

#End Region

End Class

So, I've got a wpf form, which goes out to a site, parses the html, and returns a strongly typed list of the 'href' values. (yes, this is for my own website)

I am utilizing a backgroundworker to release the hangup of the UI, and render a running progress bar.

While it works great with just the first page of the site, if I decide to Recurse the site, the progressbar hangs, while the recursion is happenning, then once the recursion is through, the progressbar comes back to life.

Can you tell me what I am doing wrong here? And possible direct me to the proper usage of said backgroundworker with the progressbar... Basically, the progressbar should run while the task is being performed, but I assume based on the code that this really isnt the case.

Here's the code-behind for the window that this is being done in:

Imports System.Threading.Tasks
Imports System.Threading

Class MainWindow

Private _previousCursor As Cursor = Mouse.OverrideCursor
Private _Spider As New Spider.SpiderIt
Private _Worker As New ComponentModel.BackgroundWorker
Private _RunCount As Integer = 0

Private Sub MainWindow_Loaded(sender As Object, e As System.Windows.RoutedEventArgs) Handles Me.Loaded
    Me.workProgress.Visibility = Windows.Visibility.Hidden
    _Worker.WorkerReportsProgress = True
    _Worker.WorkerSupportsCancellation = True
    AddHandler _Worker.DoWork, New System.ComponentModel.DoWorkEventHandler(AddressOf Spider)
    AddHandler _Worker.ProgressChanged, New System.ComponentModel.ProgressChangedEventHandler(AddressOf worker_ProgressChanged)
    AddHandler _Worker.RunWorkerCompleted, New System.ComponentModel.RunWorkerCompletedEventHandler(AddressOf worker_RunWorkerCompleted)
    Me.SiteParse.Focus()
End Sub

Private Sub SiteParseKeyDown(sender As System.Object, e As System.Windows.Input.KeyEventArgs)
    If (e.Key = Key.Return) Then
        Me.btnParseAll.IsEnabled = False
        Me.btnParseSelected.IsEnabled = False
        Me.SiteParse.IsEnabled = False
        Mouse.OverrideCursor = Cursors.Wait
        Me.workProgress.Visibility = Windows.Visibility.Visible
        _Worker.RunWorkerAsync(New Typing() With {.Url = SiteParse.Text, .Recurse = Recurse.IsChecked})
    End If
End Sub

Private Sub btnParseAll_Click(sender As Object, e As System.Windows.RoutedEventArgs) Handles btnParseAll.Click
    Me.btnParseAll.IsEnabled = False
    Me.btnParseSelected.IsEnabled = False
    Me.SiteParse.IsEnabled = False
    Dim _TL As New List(Of DGTyping)
    Using New WaitCursor
        For Each Item In DG_SiteLinks.Items
            _TL.Add(New DGTyping() With {
                    .SiteUrl = Item.SiteUrl,
                    .SiteTitle = Item.SiteTitle
                })
        Next
    End Using
    Dim _T As New ParseLinks(Me, _TL)
    _T.ShowDialog()
End Sub

Private Sub btnParseSelected_Click(sender As Object, e As System.Windows.RoutedEventArgs) Handles btnParseSelected.Click
    Me.btnParseAll.IsEnabled = False
    Me.btnParseSelected.IsEnabled = False
    Me.SiteParse.IsEnabled = False
    Dim _TL As New List(Of DGTyping)
    Using New WaitCursor
        For Each Item In DG_SiteLinks.SelectedItems
            _TL.Add(New DGTyping() With {
                    .SiteUrl = Item.SiteUrl,
                    .SiteTitle = Item.SiteTitle
                })
        Next
    End Using
    Dim _T As New ParseLinks(Me, _TL)
    _T.ShowDialog()
End Sub

#Region "Get Site Links"

Private Sub Spider(sender As Object, e As System.ComponentModel.DoWorkEventArgs)
    'Do the work here, but need to get the value of SiteParse first
    With _Spider
        .UrlToParse = DirectCast(e.Argument.Url, String)
        .ShouldRecurse = DirectCast(e.Argument.Recurse, Boolean)
        .RecurseLevels = 20
        .SpiderIt(_Worker)
    End With
End Sub

Private Sub worker_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs)
    workProgress.Value = e.ProgressPercentage
End Sub

Private Sub worker_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs)
    EndRest()
    Dim _IL As List(Of Spider.Typing.InternalLinks)
    _IL = _Spider.InternalLinks()
    Dim _TL As New List(Of DGTyping)
    For Each item In _IL
        _TL.Add(New DGTyping() With {
                .SiteUrl = item.Url,
                .SiteTitle = If(item.Title.Length > 0, item.Title, item.Content)
            })
    Next
    _IL.Clear()
    Me.DG_SiteLinks.ItemsSource = _TL
    EndSync()
End Sub

Private Sub BrowseSite(sender As Object, e As RoutedEventArgs)
    Dim _URL As String = DirectCast(sender, TextBlock).Text
    Dim _T As New Browser(_URL)
    _T.ShowDialog()
End Sub

Private Sub Window_Closing(sender As Object, e As System.ComponentModel.CancelEventArgs)
    If _Worker IsNot Nothing Then
        If _Worker.IsBusy Then
            _Worker.CancelAsync()
        End If
    End If
End Sub

Private Sub EndSync()
    _Worker.CancelAsync()
    _Worker.Dispose()
    _Spider.Dispose()
End Sub

Private Sub EndRest()
    workProgress.Value = 0
    workProgress.Visibility = Windows.Visibility.Hidden
    Me.btnParseAll.IsEnabled = True
    Me.btnParseSelected.IsEnabled = True
    Me.SiteParse.IsEnabled = True
    Mouse.OverrideCursor = _previousCursor
End Sub

Partial Public Class Typing
    Public Property Url As String
    Public Property Recurse As Boolean
End Class

Partial Public Class DGTyping
    Public Property SiteUrl As String
    Public Property SiteTitle As String
End Class

#End Region

End Class

.SpiderIt() goes out the site specified, grabs the html as an HDocument (SuperstarCoders LinqToHtml), parses it for internal links, and throws them into a strongly typed list. This is done in a seperate class assembly, and performs perfectly.

SpiderIt method and containing class:

Imports Superstar.Html.Linq
Imports System.Threading.Tasks

Public Class SpiderIt
Implements IDisposable

#Region "Public Properties"

''' <summary>
''' Specify the initial URL to parse
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public Property UrlToParse As String

''' <summary>
''' Should this recurse the internal links of the site
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public Property ShouldRecurse As Boolean = False

''' <summary>
''' Specify the number of levels to recurse
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public Property RecurseLevels As Long = 0

''' <summary>
''' Returns a message from the SpiderIt method
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public ReadOnly Property Message() As String
    Get
        Return _Msg
    End Get
End Property

''' <summary>
''' Returns a strongly typed list of internal links
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public ReadOnly Property InternalLinks() As List(Of Typing.InternalLinks)
    Get
        Return _InternalLinkList
    End Get
End Property

''' <summary>
''' Returns a strongly typed list of external links
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public ReadOnly Property ExternalLinks() As List(Of Typing.ExternalLinks)
    Get
        Return _ExternalLinkList
    End Get
End Property

#End Region

#Region "Internal Properties"

Private disposedValue As Boolean
Private _Msg As String
Private _Ctr As Long = 0
Private _InternalLinkList As New List(Of Typing.InternalLinks)
Private _ExternalLinkList As New List(Of Typing.ExternalLinks)
Private _DLer As New Downloader
Private _RCt As Long = 0

#End Region

#Region "Public Methods"

''' <summary>
''' Parse with the specified values
''' </summary>
''' <returns>Boolean</returns>
''' <remarks>Returns true or false, based on if it has completed, as well as a message
''' Spits out 2 strongly typed lists.  Both internal and external URLs
''' </remarks>
Public Function SpiderIt(ByVal _Worker) As Boolean
    For i As Integer = 1 To 99
        _Worker.ReportProgress(i)
        System.Threading.Thread.Sleep(50)
    Next
    _Worker.ReportProgress(100)
    Dim _Doc As HDocument = _DLer.DownloadHDoc(UrlToParse)
    With _Doc
        If _Doc Is Nothing Then
            _Msg = "There is no document to parse."
            Return False
        Else
            Try
                Dim _AL = .Descendants("a")
                'Parse the internal links
                ParseLinks(_AL)
                _Msg = "Internal Link List Built"
                Return True
            Catch ex As Exception
                _Msg = ex.Message
                Return False
            End Try
        End If
    End With
End Function

#End Region

#Region "Internal Methods"

#Region "Spider Helpers"

Private Sub ParseLinks(ByVal _AL As IEnumerable(Of HElement))
    Try
        Dim _Link As String, _D As HDocument
        For i As Long = 0 To _AL.Count - 1
            If _AL(i).Attribute("href") IsNot Nothing AndAlso Not (_AL(i).Attribute("href").Value.Contains("//") OrElse
                    _AL(i).Attribute("href").Value.Contains("http://") OrElse
                    _AL(i).Attribute("href").Value.Contains("https://") OrElse
                    _AL(i).Attribute("href").Value.Contains("ftp://") OrElse
                    _AL(i).Attribute("href").Value.Contains("mailto:") OrElse
                    _AL(i).Attribute("href").Value.Contains("#")) Then
                _Link = UrlToParse & "/" & _AL(i).Attribute("href").Value
                If Not (_InternalLinkList.Any(Function(x) x.Url = _Link.Replace("//", "/").Replace("http:/", "http://").Replace("https:/", "https://"))) Then
                    AddInternalLinks(_Link.Replace("//", "/").Replace("http:/", "http://").Replace("https:/", "https://"),
                                     If(_AL(i).Attribute("target") Is Nothing,
                                         String.Empty,
                                         _AL(i).Attribute("target").Value),
                                     _AL(i).Value,
                                     If(_AL(i).Attribute("title") Is Nothing,
                                         String.Empty,
                                         _AL(i).Attribute("title").Value))
                    If ShouldRecurse Then
                        _RCt += 1
                        If _RCt <= RecurseLevels Then
                            _D = _DLer.DownloadHDoc(_Link)
                            ParseLinks(_D.Descendants("a"))
                        End If
                    End If
                End If
            Else
                _Link = _AL(i).Attribute("href").Value
                If Not (_ExternalLinkList.Any(Function(x) x.Url = _Link)) Then
                    AddExternalLinks(_Link,
                                     If(_AL(i).Attribute("target") Is Nothing,
                                         String.Empty,
                                         _AL(i).Attribute("target").Value),
                                     _AL(i).Value,
                                     If(_AL(i).Attribute("title") Is Nothing,
                                         String.Empty,
                                         _AL(i).Attribute("title").Value))
                End If
            End If
        Next
    Catch ex As Exception
        _Msg += ex.StackTrace
    End Try
End Sub

Private Sub AddExternalLinks(ByVal _Link As String, ByVal _Target As String, ByVal _Content As String, ByVal _Title As String)
    Try
        _ExternalLinkList.Add(New Typing.ExternalLinks With {
                            .Url = _Link,
                            .Content = _Content,
                            .Target = _Target,
                            .Title = _Title
                        })
    Catch ex As Exception
        _Msg += ex.StackTrace
    End Try
End Sub

Private Sub AddInternalLinks(ByVal _Link As String, ByVal _Target As String, ByVal _Content As String, ByVal _Title As String)
    Try
        _InternalLinkList.Add(New Typing.InternalLinks With {
                            .Url = _Link,
                            .Content = _Content,
                            .Target = _Target,
                            .Title = _Title
                        })
    Catch ex As Exception
        _Msg += ex.StackTrace
    End Try
End Sub

#End Region

#Region "IDisposable Support"

Protected Overridable Sub Dispose(disposing As Boolean)
    If Not Me.disposedValue Then
        If disposing Then
        End If
        _Msg = String.Empty
        _InternalLinkList.Clear()
        _ExternalLinkList.Clear()
        _DLer.Dispose()
    End If
    Me.disposedValue = True
End Sub

Public Sub Dispose() Implements IDisposable.Dispose
    Dispose(True)
    GC.SuppressFinalize(Me)
End Sub

#End Region

#End Region

End Class

原文:https://stackoverflow.com/questions/13997801
更新时间:2023-12-02 18:12

最满意答案

您的脚本创建的ScritpDb只能通过该脚本的代码访问 - 只是因为您拥有已发布脚本的URL,或者即使您拥有某种形式的代码,也不会授予您访问ScriptDb的权限。

但是,如果传入某个可预测的参数,如果你在doGet中盲目地将所有数据转储到HTML输出,那么这就是坏事。 但这将被视为编程错误。

简而言之 - 如果您的ScriptDb使用适当的Apps脚本正确包装,那么访问该ScriptDb是安全的。

如果你分担一些你担心的可能不安全的代码,我可以澄清一下。


The ScritpDb your script creates can only be accessed accessed by that script's code - just because you have the URL to the published script or even if you have code in some form DOES NOT give you access to the ScriptDb.

However, lets say if in your doGet if you are blindly dumping out all the data to HTML output if a certain predictable parameter is passed in, then that is bad. But that would be considered a programming error.

So in short - if your ScriptDb is properly wrapped with the appropriate Apps Script, then access to that ScriptDb is secure.

I can clarify more if you share some code around what you worry might be insecure.

相关问答

更多
  • 您的脚本创建的ScritpDb只能通过该脚本的代码访问 - 只是因为您拥有已发布脚本的URL,或者即使您拥有某种形式的代码,也不会授予您访问ScriptDb的权限。 但是,如果传入某个可预测的参数,如果你在doGet中盲目地将所有数据转储到HTML输出,那么这就是坏事。 但这将被视为编程错误。 简而言之 - 如果您的ScriptDb使用适当的Apps脚本正确包装,那么访问该ScriptDb是安全的。 如果你分担一些你担心的可能不安全的代码,我可以澄清一下。 The ScritpDb your script ...
  • setBackgroundColor(color)是Class Range的一个方法,换句话说,首先你应该得到一个范围对象,然后你可以调用该对象的setBackgroundColor(color) values[i][0]不是引用范围的适当方式,因为此变量保存单元格内容而不是单元格本身。 有几种方法可以引用一个范围。 基本形式是A1表示法,以及行号和列号。 一个非常简单的例子 function example1(){ var range = SpreadsheetApp.getActiveRange() ...
  • 而不是有100个不同的脚本,你应该只有一个脚本,用var url = SitesApp.getActivePage().getUrl();来识别它的启动位置var url = SitesApp.getActivePage().getUrl(); 然后您决定根据您所在的页面显示值。 instead of having 100 differents scripts, you should only have one script that identify where it's launch from with ...
  • 第三个过滤器无法使用Google Apps脚本。 1过滤器 - 人口(工作)2过滤器 - 特征(工作)3过滤器 - 过滤器(dos不工作).. the third filter is not working to Google Apps Script. 1 filter - Population (working) 2 filter - Characteristic (working) 3 filter - Filter (dos not work)..
  • 它在完全不同的记忆空间中。 我不认为“ reentrant ”是这里最准确的术语,因为没有一个代码的中断来运行另一个代码。 他们都同时并安全地发生。 我不确定正确的术语是什么。 我想你可以说整个环境都是“线程安全的”,因为它们在不同的线程/进程中执行,并且没有共享变量。 您只需要处理共享资源,如常见的电子表格或文档属性等。 - 编辑 很难理解你的设置,但无论如何我会建议一种方法。 首先,我建议您只有一个脚本,并且只与用户共享其部署的URL(而不是脚本本身)。 关于将电子表格与BigQuery结合起来,对Bi ...
  • 应用脚本缓存服务 每个密钥最多可以缓存100KB ,您不应该只有“200”字符的问题。 更严格的限制仅适用于250个字符的密钥。 我在您的代码中看到的主要问题是您尝试缓存解析的数据而不是文本。 除非你的密钥那么大(在这种情况下我推荐你使用enconding),这应该工作: function _fetchJiraData(targetIssue) { var jsonText = cache.get(targetIssue); if (jsonText === null) { //...pre ...
  • 在我阅读了一些文档( 这里和这里 )后,简单的解决方案。 我做了三件事: 剥掉了身体和头部的标签。 这感觉非常奇怪,但它奏效了。 在我的code.gs文件中将我的沙箱模式更改为IFRAME 将以下代码添加到code.gs文件中调用的html模板中 在code.gs中: function doGet() { var html = HtmlService .createTemplateFromFile('index') .evaluate() .setTitle('Font Test') . ...
  • “Google Apps脚本失败摘要”包含指向包含相关脚本的文件的链接。 仔细阅读。 The "Summary of failures for Google Apps Script" includes a link to the file holding the related script. Read it carefully.
  • 此问题已报告给Google。 谷歌正在努力。 在问题跟踪器上加注此问题。 This problem is reported to Google. Google works on it. Star this issue on the issue tracker.
  • 您可以配置允许一个脚本访问Apps脚本用户文件的设置。 用户需要使用自己的Google帐户登录。 您可以将Apps脚本脚本发布为以任何方式运行,并将应用程序执行为: 用户访问Web App 。 这要求用户使用他们的Google帐户登录,并允许脚本访问用户文件。 属性服务用于存储。 它不设置或授予权限。 不同类型属性的细分比较显示在: 物业商店的比较 You can configure settings that will allow one script to access the files of the ...

相关文章

更多

最新问答

更多
  • 获取MVC 4使用的DisplayMode后缀(Get the DisplayMode Suffix being used by MVC 4)
  • 如何通过引用返回对象?(How is returning an object by reference possible?)
  • 矩阵如何存储在内存中?(How are matrices stored in memory?)
  • 每个请求的Java新会话?(Java New Session For Each Request?)
  • css:浮动div中重叠的标题h1(css: overlapping headlines h1 in floated divs)
  • 无论图像如何,Caffe预测同一类(Caffe predicts same class regardless of image)
  • xcode语法颜色编码解释?(xcode syntax color coding explained?)
  • 在Access 2010 Runtime中使用Office 2000校对工具(Use Office 2000 proofing tools in Access 2010 Runtime)
  • 从单独的Web主机将图像传输到服务器上(Getting images onto server from separate web host)
  • 从旧版本复制文件并保留它们(旧/新版本)(Copy a file from old revision and keep both of them (old / new revision))
  • 西安哪有PLC可控制编程的培训
  • 在Entity Framework中选择基类(Select base class in Entity Framework)
  • 在Android中出现错误“数据集和渲染器应该不为null,并且应该具有相同数量的系列”(Error “Dataset and renderer should be not null and should have the same number of series” in Android)
  • 电脑二级VF有什么用
  • Datamapper Ruby如何添加Hook方法(Datamapper Ruby How to add Hook Method)
  • 金华英语角.
  • 手机软件如何制作
  • 用于Android webview中图像保存的上下文菜单(Context Menu for Image Saving in an Android webview)
  • 注意:未定义的偏移量:PHP(Notice: Undefined offset: PHP)
  • 如何读R中的大数据集[复制](How to read large dataset in R [duplicate])
  • Unity 5 Heighmap与地形宽度/地形长度的分辨率关系?(Unity 5 Heighmap Resolution relationship to terrain width / terrain length?)
  • 如何通知PipedOutputStream线程写入最后一个字节的PipedInputStream线程?(How to notify PipedInputStream thread that PipedOutputStream thread has written last byte?)
  • python的访问器方法有哪些
  • DeviceNetworkInformation:哪个是哪个?(DeviceNetworkInformation: Which is which?)
  • 在Ruby中对组合进行排序(Sorting a combination in Ruby)
  • 网站开发的流程?
  • 使用Zend Framework 2中的JOIN sql检索数据(Retrieve data using JOIN sql in Zend Framework 2)
  • 条带格式类型格式模式编号无法正常工作(Stripes format type format pattern number not working properly)
  • 透明度错误IE11(Transparency bug IE11)
  • linux的基本操作命令。。。