andycruce Ответов: 1

Использование фонового рабочего


Я попытался использовать отдельный поток с методом invoke для записи в свойства WinForm из потока, не являющегося графическим интерфейсом. После того, как ничего не получилось, я узнал о фоновом работнике, который, кажется, является более простым решением. Я нашел пример, что из программы Form1 запускался таймер, который периодически вызывал функцию background worker doWork. Я создал форму с одной меткой и фоновым работником под названием bgw. Я настроил три прерывания dowork, прогресс изменился и runworkercompleted. Я также установил WorkerReportsProgress и WorkerSupports Cancellation в True. Я скопировал код с

c# - использование таймера с Backgroundworker для обеспечения вызова метода doWork - Code Review Stack Exchange[^]

Вот код, который я использовал:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace Background_Worker_Test
{
    public partial class Form1 : Form
    {

        //  Setup to call Background worker perioically
        System.Windows.Forms.Timer tmrCallBgWorker;  // timer to call Backgroundworker

        //  our Background Worker is backgroundWorker1

        //  timer to make sure BackgroundWorker Gets Called
        System.Threading.Timer tmrEnsureWorkerGetsCalled;

        // object used for saft access;
        object lockObject = new object();

        public int TestInt;


        public Form1()
        {
            InitializeComponent();

            // This timer call BackgroudnWorker at regular intervals
            tmrCallBgWorker = new System.Windows.Forms.Timer();
            tmrCallBgWorker.Tick += new EventHandler(tmrCallBgWorker_tick);
            tmrCallBgWorker.Interval = 1000;

            bgw.DoWork += new DoWorkEventHandler(bgw_DoWork);
            bgw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgw_RunWorkerCompleted);

        }

        void tmrCallBgWorker_tick(object sender, EventArgs e)
        {
            if (Monitor.TryEnter(lockObject))
            {
                try
                {
                    //  if bgw is not busy call the worker
                    if (!bgw.IsBusy)
                        bgw.RunWorkerAsync();

                }
                finally
                {
                    Monitor.Exit(lockObject);
                }
            }
            else
            {
                // as te bgw is busy, start a new timer that will call
                //  try to call bgw again after some time
                tmrEnsureWorkerGetsCalled = new System.Threading.Timer
                    (new TimerCallback(tmrEnsureWorkerGetsCalled_Callback), null, 0, 10);
            }
        }

        void tmrEnsureWorkerGetsCalled_Callback(object obj)
        {
            try
            {
                if (!bgw.IsBusy)
                    bgw.RunWorkerAsync();

            }
            finally
            {
                Monitor.Exit(lockObject);
            }
            tmrEnsureWorkerGetsCalled = null;
        }





        private void bgw_DoWork(object sender, DoWorkEventArgs e)
        {
            label1.Text = string.Format("In do work {0:N3}", TestInt);
        }

        private void bgw_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {

        }

        private void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {

        }
    }
}


Dode проходит через метод Form1 () и зависает. Насколько я могу судить,он продолжает переинициализироваться. Я новичок в C#, но не понимаю, почему это не работает. Кажется гораздо более прямолинейным, чем новый подход к потоку с требуемым материалом invoke. Помогите!

Спасибо,

Энди Крус

Что я уже пробовал:

Начал использовать метод потока для записи в свойства WinForm, но не смог заставить его работать. Перешел к использованию Backgroud Worker и нашел то, что мне показалось простым примером, который я не могу запустить.

1 Ответов

Рейтинг:
2

OriginalGriff

Вы не запускаете таймер ...

public Form1()
{
    InitializeComponent();

    // This timer call BackgroudnWorker at regular intervals
    tmrCallBgWorker = new System.Windows.Forms.Timer();
    tmrCallBgWorker.Tick += new EventHandler(tmrCallBgWorker_tick);
    tmrCallBgWorker.Interval = 1000;

    bgw.DoWork += new DoWorkEventHandler(bgw_DoWork);
    bgw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgw_RunWorkerCompleted);

}
Добавьте эту строку:
tmrCallBgWorker.Start();

После этой строки:
tmrCallBgWorker.Interval = 1000;