代码之家  ›  专栏  ›  技术社区  ›  Michael Neale

在Windows上实现线程安全的ftp文件获取守护进程

  •  0
  • Michael Neale  · 技术社区  · 6 年前

    我开始实现一个简单的守护进程,它在后台工作程序组件的帮助下从ftp位置获取文件,以保证线程的安全性。虽然我有点感觉我朝着正确的方向前进,但我对所涉及的技术并不完全熟悉,因此在整个应用程序生命周期中不是很轻松,我说有些场景我肯定还不知道如何处理,也就是说,如何处理停止事件,如果服务停止,会发生什么?当工人在运行时,等等。我想下面这段代码几乎不代表我要实现的目标:

    #region Daemon Events
    protected override void OnStart(string[] args)
    {
        this.transferBackgroundWorker.RunWorkerAsync();
    }
    
    protected override void OnStop()
    {
                this.transferBackgroundWorker.CancelAsync(); // Thanks Wolfwyrd!
    }
    #endregion
    
    #region BackgroundWorker Events
        private void transferBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;
            worker.WorkerSupportsCancellation = true;
    
            #region FTP Download
    
            FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create(Daemon.FTP_HOST);
            ftpRequest.Method = WebRequestMethods.Ftp.DownloadFile;
            ftpRequest.Credentials = new NetworkCredential(Daemon.FTP_USER, Daemon.FTP_PASS);
            FtpWebResponse ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
    
            using(Stream ftpResponseStream = ftpResponse.GetResponseStream())
            {
                using (StreamWriter sw = File.CreateText(FILE_NAME))
                {
                    sw.WriteLine(ftpResponseStream);
                    sw.Close();
                }
                ftpResponse.Close();
            }
            #endregion
    
            e.Result = "DEBUG: Download complete" + ftpResponse.StatusDescription;
        }
    
    private void transferBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        if (e.Error != null)
        {
            EventLog.WriteEntry("Exception caught: " + e.Error.Message);
        }
        else
        {
            EventLog.WriteEntry(e.Result.ToString());
        }
    }
    #endregion
    

    任何建议都会受到赞赏。非常感谢您的帮助。

    编辑 :刚刚重新实现了FTP文件提取。

    1 回复  |  直到 15 年前
        1
  •  2
  •   Wolfwyrd    15 年前

    后台工作人员的工作方式是将某个任务分离到独立于调用应用程序的单独后台线程上。后台工作人员的生命周期遵循以下模式:

    • 创建后台工作进程(即background worker bgw=new…)
    • 调用bgw.runworkerasync backgroundworker启动单独的后台线程,并在此线程上调用dowork方法
    • 引发可选通知事件,这些事件通过调用bgw.reportProgress()引发,并在BackgroundWorkers父线程中订阅(并对其执行)
    • 可能会发生可选取消,当调用bgw.cancelAsync()时会发生这种情况。此调用可能来自任何可以访问BackgroundWorker对象的线程。您可以通过检查DoWork方法中的CancellationPending属性来确认取消。
    • BackgroundWorker DoWork方法通过自然完成或由于异常终止(即DoWork方法中发生未处理的异常)完成,调用-RunWorkerCompleted方法。

    为了提供关于原始问题的建议,您似乎要做的是将BackgroundWorker标记为支持取消(bgw.workersupportscancellation=true),并让停止事件调用BackgroundWorker上的CancelAsync()方法。更新DoWork方法以在适当的时间轮询“CancellationPending”属性,并在服务处于已知状态时执行取消操作。