3

场景:我的应用程序中有一个DataGrid,其中onclikcing每一行的值都填充在texboxes下面。我将更新这些值,单击保存时,该过程需要更多时间才能完成。

所以我写了一个后台工作者来让这个进程运行asynchronously。单击每一行时,会backgroundworker创建一个实例并完成该过程。在该更新期间,用户将选择网格的第二行并更新该值。所以这将创建另一个实例,并且该进程将在后台运行。

现在,如果用户选择网格的第一行,则两个更新过程都在运行时,应该会显示一条消息,显示“该过程仍在运行”。

//代码:

' 事件的 OnClick

         var bw = new BackgroundWorker();
          bw.WorkerReportsProgress = true;
          bw.DoWork += delegate {
              SaveDetails();
          };
          bw.RunWorkerCompleted += delegate {
              MessageBox.Show("Completed");
          };
          bw.RunWorkerAsync();

'保存方法

 public void SaveDetails()
    {
        for (int i = 0; i < 10;i++ )
        {
            System.Threading.Thread.Sleep(5000);
            MessageBox.Show("Hi");

        }
    }

如何访问先前创建的后台工作实例并检查进程状态并显示消息?

注意:可能有许多进程同时运行,所以我应该能够访问任何进程。

这可能吗?

4

4 回答 4

2

您可以将BackgrounWorker创建的任何内容存储在 aList中以随时引用它们,但或者您可以创建一个任务并将任何待处理的进程存储在那里,因此您随时Queue只有一个。BackgroundWorker

将 BackgroundWorkers 存储在列表中

例如,创建一个List(Of BackgroundWorker)可以在代码中您需要的任何位置访问的。每次创建新的BackgroundWorker时,将其添加到List

mylist.Add(bw)

你有很多选项可以在以后访问正确backgroundworker的。最简单的方法是创建自己的类,该类将具有标识符(DataGrid例如 的行)和backgroundworker. 这样,您list将属于此类,而不是BackgroundWorkers

myClass.BackgroundWorkerProperty = bw
myClass.id = myId
myList.Add(myClass)

使用队列运行任务

创建一个Queue具有运行任务信息的类型。例如DataGrid,如果足够的话,该行将是类型Integer(索引),然后在每次backgroundworker运行时添加它:

myQueue.Add(myRow)

每次backgroundworker完成时,检查Queue并运行存储的下一个任务。

于 2013-09-03T08:58:51.347 回答
1

您可以使用的Tag属性DataGridViewRow

var bw = new BackgroundWorker();
row.Tag = bw;

所以你可以访问它。

于 2013-09-03T09:04:32.367 回答
1

如果您使用的是 .NET 4.5,我建议使用 Async/Await 而不是后台线程来解决您的问题,因为它的编程风格简单高效,如下所示:

 public partial class Form1 : Form
    {
        List<Task<bool>> taskList = new List<Task<bool>>();
        public Form1()
        {
            InitializeComponent();
        }

        private async void button1_Click(object sender, EventArgs e)
        {            
            Task<bool> task = Task.Run(() => SaveDetails());
            MessageBox.Show(task.Id + " started.");
            taskList.Add(task);
            var isSuccess = await task;
        }
        public bool SaveDetails()
        {
            for (int i = 0; i < 10; i++)
            {
                System.Threading.Thread.Sleep(5000);
                //MessageBox.Show("Finishing.");                
            }
            return true;
        }       

        private void button2_Click(object sender, EventArgs e)
        {            
            foreach (var task in taskList)
            {                
                if (task.IsCompleted == true)
                    MessageBox.Show(task.Id + " Completed.");
            }        
        }
    }

我创建了第二个按钮单击事件来访问和显示所有当前完成的任务。另外,请注意您可以task.Id用作网格行的行标识符。

希望有帮助。

于 2013-09-03T09:47:13.827 回答
0

嗯,这很容易。将BackgroundWorker作为成员放入您的表单中,然后您可以从任何地方访问它:

BackgroundWorker bg;

public Form1()
{
    bg = new BackgroundWorker();
}


private void button1_Click(object sender, EventArgs e)
{
         if(bg.IsBusy)
         {
             // show the message
         }
         else
         {
              bw.WorkerReportsProgress = true;
              bw.DoWork += delegate {
                 SaveDetails();
              };
              bw.RunWorkerCompleted += delegate {
                 MessageBox.Show("Completed");
              };
              bw.RunWorkerAsync();
         }
}
于 2013-09-03T08:58:13.823 回答