c#捕获后台工作者的响应

时间:2014-03-04 15:21:06

标签: c# multithreading

我对此很新,所以请放轻松我。我基本上是用按钮开始后台进程。在同一个按钮上我想捕获响应。我知道有一个runworkercompleted方法很好,但我希望按钮单击以接收响应。在这个例子中,我创建了一个字典,任务填充了一些文本。希望启动线程的按钮能够从字典中读取值。

这是代码:

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

namespace background_worker
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        Dictionary<Guid , string> _taskdictionary = new Dictionary<Guid, string>();


        private void button1_Click(object sender, EventArgs e)
        {
            //create new task id (guid) and start task
            Guid taskID = Guid.NewGuid();
            backgroundWorker1.RunWorkerAsync(taskID);

            //how do i know when i can grab the result of the threaded job?
            //i know it will be in dictionary but how do i get hold of it
            if (_taskdictionary.ContainsKey(taskID))
                this.Text = _taskdictionary[taskID];
        }


        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            //task will be added to taskdictionary with result

            Guid taskid = (Guid)e.Argument;
            if (!_taskdictionary.ContainsKey(taskid))
                _taskdictionary.Add(taskid, "this is the result");

            #region
            //task will log to file 
            string lines = "this is the result";
            System.IO.StreamWriter file = new System.IO.StreamWriter("c:\\result" + taskid.ToString() + ".txt");
            file.WriteLine(lines);
            file.Close();
            #endregion

            e.Result = "complete";
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            //MessageBox.Show((string)e.Result);

        }
    }
}

1 个答案:

答案 0 :(得分:1)

您可以使用C#5.0的异步功能来处理这种情况,甚至不使用BackgroundWorker:

private async void button1_Click(object sender, EventArgs e)
{
    var result = await Task.Run(() => ComputeResult());
    DoStuffWithResult(result);
}

另一个选项,如果在按钮点击中编写代码很重要,那就是在按钮点击中通过匿名方法附加BGW的事件处理程序:

private void button1_Click(object sender, EventArgs e)
{
    var worker = new BackgroundWorker();
    worker.DoWork += ComputeResult;
    worker.RunWorkerCompleted += (s, args) =>
    {
        DoStuffWithResult(args.Result);
    };
    worker.RunWorkerAsync();
}

如果你不想这样做,那么答案很简单就是你做不到。这里的重点是按钮点击需要在工作完成之前完成,这样它就可以返回其调用者(消息循环),以便它可以继续处理消息,以防止UI从冻结。