0

基本的に、BackgroundWorkerコンポーネントを使用して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ファイルのフェッチを再実装しました。

4

1 に答える 1

2

BackgroundWorker は、呼び出し元のアプリケーションから独立した別のバックグラウンド スレッドにいくつかのタスクをスピンオフすることによって機能します。バックグラウンド ワーカーのライフサイクルは、次のパターンに従います。

  • バックグラウンド ワーカーを作成します (つまり、BackgroundWorker bgw = new ...)
  • bgw.RunWorkerAsync を呼び出します 別のバックグラウンド スレッドが BackgroundWorker によって開始され、このスレッドで DoWork メソッドが呼び出されます
  • オプションの通知イベントが発生します。これらは bgw.ReportProgress() を呼び出すことによって発生し、BackgroundWorkers 親スレッドでサブスクライブ (および処理) されます
  • オプションのキャンセルが発生する場合があります。これは bgw.CancelAsync() が呼び出されたときに発生します。この呼び出しは、BackgroundWorker オブジェクトにアクセスできる任意のスレッドから発生する可能性があります。DoWork メソッドの CancellationPending プロパティをチェックして、キャンセルを受け入れるかどうかはあなた次第です。
  • BackgroundWorker DoWork メソッドは、自然終了または異常終了 (つまり、DoWork メソッドで未処理の例外が発生) により終了します。 - RunWorkerCompleted メソッドが呼び出されます。

元の質問に対するアドバイスを提供するには、バックグラウンド ワーカーにキャンセルをサポートするフラグを立てて (bgw.WorkerSupportsCancellation = true)、停止イベントに BackgroundWorker の CancelAsync() メソッドを呼び出すようにします。DoWork メソッドを更新して、適切な時点で「CancellationPending」プロパティをポーリングし、サービスが既知の状態のままになったときにキャンセルを実行します。

于 2009-07-28T14:10:32.410 に答える