2

バックグラウンドワーカーをキャンセルして破棄すると、VSスレッドリストから消えたにもかかわらず、アプリケーションが閉じるのを待っているアプリケーションにビジー状態が報告され続けます。また、RunWorkerCompletedイベントが発生することはありません。

デバッグは、コードが終了し、実行が保留されていないことを示しています。

.IsBusyチェックを削除すると、VSは「このBackgroundWorkerは現在ビジーであり、複数のタスクを同時に実行できない」と報告します。

VSにリストされなくなったスレッドが閉じた後も動作し続ける理由がわかりません。

     private void UpdateTimeLine()
        {

        txtb_timeline.Text = "Updating...";


        startTimelineUpdater.DoWork += new DoWorkEventHandler(startTimelineUpdater_DoWork);
        startTimelineUpdater.RunWorkerAsync("hometimeline");

        startTimelineUpdater.WorkerReportsProgress = true;
        startTimelineUpdater.ProgressChanged += new ProgressChangedEventHandler
                                             (startTimelineUpdater_ProgressChanged);
        startTimelineUpdater.WorkerSupportsCancellation = true;

    }


   void startTimelineUpdater_DoWork(object sender, DoWorkEventArgs e)
    {
        //begin the thread to maintain updates of SQL          
        beginRegUpdateTimeline.DoWork += new DoWorkEventHandler(beginRegUpdateTimeline_DoWork);
        beginRegUpdateTimeline.RunWorkerAsync();
        beginRegUpdateTimeline.WorkerSupportsCancellation = true;

        while (true)
        {
            List<string[]> sqlset;

            Xtweet getSQL = new Xtweet();

            if(e.Argument.ToString() == "hometimeline")
            {
                sqlset = getSQL.CollectLocalTimelineSql();
            }
            else
            {
                sqlset = getSQL.CollectLocalTimelineSql(Int64.Parse(e.Argument.ToString()));
            }

            int i = 0;
            while (i < 10)
            {
                foreach (var stringse in sqlset)
                {
                    StringBuilder sb = new StringBuilder();

                    sb.Append(stringse[0]);
                    sb.Append(": ");
                    sb.Append(stringse[1]);
                    sb.Append(" @ ");
                    sb.Append(stringse[2]);

                    sb.Append("\n");

                    BackgroundWorker bkgwk = sender as BackgroundWorker;
                    bkgwk.ReportProgress(0, sb.ToString());

                    Thread.Sleep(1000);

                    i++;

                    if(startTimelineUpdater.CancellationPending)
                    {
                        e.Cancel = true;
                        startTimelineUpdater.Dispose();
                        break;
                    }

                }
                if (e.Cancel == true)
                {
                    break;
                }

            }

            if (e.Cancel == true)
            {
                break;

            }

        }


    }

    /// <summary>
    /// Handles the DoWork event of the beginRegUpdateTimeline control.
    /// Updates the timeline sql on a regular basis
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">The <see cref="System.ComponentModel.DoWorkEventArgs"/> instance containing the event data.</param>
    void beginRegUpdateTimeline_DoWork(object sender, DoWorkEventArgs e)
    {

        while (true)
        {
            //update time in seconds
            int secs = 10;

            Xtweet.PreSqlDataCollection(null,null);
            Thread.Sleep(secs*1000);

            if(beginRegUpdateTimeline.CancellationPending)
            {
                e.Cancel = true;
                beginRegUpdateTimeline.Dispose();
                break;
            }


        }


    }

    private void startTimelineUpdater_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        txtb_timeline.Text = e.UserState.ToString();

    }   
4

1 に答える 1

3

スレッドのスリープ後にApplication.DoEventsを呼び出します。

ここで述べたように:

BackgroundWorkerは、UIスレッドが制御を取得するまで実行されたことを報告しません。

アップデート:

これはWPFであるため、 Dispatcherを使用する必要があります

于 2012-04-08T13:10:10.923 に答える