使用后台工作者 [英] Using background worker

查看:93
本文介绍了使用后台工作者的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试使用带有invoke方法的单独线程从非GUI线程写入WinForm属性。什么都没有工作后我发现了背景工人,这似乎是一个更容易的解决方案。我找到了一个例子,从Form1程序启动了一个定时器,它会定期调用后台工作器的doWork函数。我创建了一个带有单个标签的表单和一个名为bgw的后台工作程序。我设置了三个中断dowork,进度改变和runworkercompleted。我还将WorkerReportsProgress和WorkerSupports Cancellation设置为True。我复制了代码来自



c# - 使用Timer与Backgroundworker一起确保调用doWork方法 - 代码审查堆栈交换 [ ^ ]



以下是我使用的代码:



 使用系统; 
使用 System.Collections.Generic;
使用 System.ComponentModel;
使用 System.Data;
使用 System.Drawing;
使用 System.Linq;
使用 System.Text;
使用 System.Threading;
使用 System.Windows.Forms;

命名空间 Background_Worker_Test
{
public partial class Form1:Form
{

// 设置为perioically调用后台工作程序
System.Windows.Forms.Timer tmrCallBgWorker; // 调用Backgroundworker的计时器

// 我们的后台工作者是backgroundWorker1

// 用于确保调用BackgroundWorker的计时器
System.Threading.Timer tmrEnsureWorkerGetsCalled;

// 用于saft访问的对象;
object lockObject = new object ();

public int TestInt;


public Form1()
{
InitializeComponent();

// 此计时器定期调用BackgroudnWorker
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))
{
尝试
{
// 如果bgw不忙如果(!bgw.IsBusy)
bgw.RunWorkerAsync();请致电工人


}
finally
{
Monitor.Exit(lockObject);
}
}
else
{
// 当te bgw忙,启动一个新的计时器,它将调用
// 尝试在一段时间后再次调用bgw
tmrEnsureWorkerGetsCalled = new System.Threading.Timer
new TimerCallback(tmrEnsureWorkerGetsCalled_Callback), null 0 10 );
}
}

void tmrEnsureWorkerGetsCalled_Callback( object obj)
{
尝试
{
如果 (!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#的新手,但不知道为什么这不起作用。看起来更直接的是新线程接近调用所需的东西。帮助!



谢谢,



安迪克鲁斯



我尝试过:



开始使用线程方法写入WinForm属性但无法正常工作。转移到使用Backgroud Worker并发现我认为是一个我无法运行的简单示例。

解决方案

你没有启动计时器......

  public  Form1()
{
InitializeComponent();

// 此计时器定期调用BackgroudnWorker
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 ; 


I tried using a separate thread with an invoke method to write to WinForm properties from a non GUI thread. After getting nothing to work I found out about Background Worker which seems to be an easier solution. I found an example that from the Form1 program started a timer that would call the background worker doWork function periodically. I created a form with a single label and a Background Worker called bgw. I setup the three interrupts dowork, progress changed and runworkercompleted. I also set WorkerReportsProgress and WorkerSupports Cancellation to True. I copied the code from

c# - Using Timer with Backgroundworker to ensure the doWork method is called - Code Review Stack Exchange[^]

Here is the code I used:

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)
        {

        }
    }
}



The dode goes through the Form1() method and the hangs. As near as I can tell it is continuing to reinitialize. I'm new to C# but can't see why this doesn't work. Seems much more straight forward that the new thread approach with the invoke stuff required. HELP!

Thanks,

Andy Cruce

What I have tried:

Started using a thread method to write to WinForm Properties but couldn't get that working. Moved to using Backgroud Worker and found what I thought was a simple example that I can't get to run.

解决方案

You don't start the timer ...

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);

}

Add this line:

tmrCallBgWorker.Start();


After this line:

tmrCallBgWorker.Interval = 1000;


这篇关于使用后台工作者的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆