Winforms的背景工作者没有更新TextBox

时间:2017-12-12 20:12:03

标签: c# winforms asynchronous backgroundworker

我正在尝试使用后台工作程序为我的winform添加一个取消按钮。

我添加了以下语法,但文本框永远不会像我尝试实现后台工作程序之前那样更新任何进度。

public Form1()
{
    AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
    {
        string resourceName = new AssemblyName(args.Name).Name + ".dll";
        string resource = Array.Find(this.GetType().Assembly.GetManifestResourceNames(), element => element.EndsWith(resourceName));

        using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resource))
        {
            Byte[] assemblyData = new Byte[stream.Length];
            stream.Read(assemblyData, 0, assemblyData.Length);
            return Assembly.Load(assemblyData);
        }
    };
    InitializeComponent(); 
    backgroundWorker1.WorkerReportsProgress = true;  
    backgroundWorker1.WorkerSupportsCancellation = true;
}
private void btnQuery_Click(object sender, EventArgs e)
{
    backgroundWorker1.RunWorkerAsync();
}

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{

        //Iterating the array
        foreach (string s in sxc)
        {
            txt_ProgressDetails.Visible = true;
            AppendTextBoxLine("Getting Data For " + s);

            //Put data into DataTable
            PopulateDT(s);
        }

        //If the cancel button was pressed
        if (backgroundWorker1.CancellationPending)
        {
            e.Cancel = true;
            return;
        }
}

    private void AppendTextBoxLine(string statusMessage)
    {
        if (txt_ProgressDetails.Text.Length > 0)
            txt_ProgressDetails.AppendText(Environment.NewLine);
        txt_ProgressDetails.AppendText(statusMessage);
    }

1 个答案:

答案 0 :(得分:2)

BackgroundWorker的Do_Work事件在非STA线程中运行,您无法从那里更新UI。您可以重写代码以使用InvokeRequredInvoke方法从创建它们的线程更新UI元素。

将此添加到您的表单:

delegate void UpdateUICallback(string statusMessage);

并将您的AppendTextBoxLine方法更改为:

if (InvokeRequired)
{
    UpdateUICallback d = new UpdateUICallback(AppendTextBoxLine);
    this.Invoke(d, new object[] {statusMessage});
}
else
{
    if (txt_ProgressDetails.Text.Length > 0)
            txt_ProgressDetails.AppendText(Environment.NewLine);
    txt_ProgressDetails.AppendText(statusMessage);
}

因此您的代码将如下所示:

public Form1()
{
    AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
    {
        string resourceName = new AssemblyName(args.Name).Name + ".dll";
        string resource = Array.Find(this.GetType().Assembly.GetManifestResourceNames(), element => element.EndsWith(resourceName));

        using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resource))
        {
            Byte[] assemblyData = new Byte[stream.Length];
            stream.Read(assemblyData, 0, assemblyData.Length);
            return Assembly.Load(assemblyData);
        }
    };
    InitializeComponent(); 
    backgroundWorker1.WorkerReportsProgress = true;  
    backgroundWorker1.WorkerSupportsCancellation = true;
}
private void btnQuery_Click(object sender, EventArgs e)
{
    backgroundWorker1.RunWorkerAsync();
}

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{

        //Iterating the array
        foreach (string s in sxc)
        {
            txt_ProgressDetails.Visible = true;
            AppendTextBoxLine("Getting Data For " + s);

            //Put data into DataTable
            PopulateDT(s);
        }

        //If the cancel button was pressed
        if (backgroundWorker1.CancellationPending)
        {
            e.Cancel = true;
            return;
        }
}

delegate void UpdateUICallback(string statusMessage);
private void AppendTextBoxLine(string statusMessage)
{
    if (InvokeRequired)
    {
        UpdateUICallback d = new UpdateUICallback(AppendTextBoxLine);
        this.Invoke(d, new object[] {statusMessage});
    }
    else
    {
        if (txt_ProgressDetails.Text.Length > 0)
                txt_ProgressDetails.AppendText(Environment.NewLine);
        txt_ProgressDetails.AppendText(statusMessage);
    }
}