场景:我的应用中有一个DataGrid
,每行onclikcing
,值会在下面的texboxes
中填充。我将更新这些值,当点击保存时,该过程需要更多时间才能完成。
所以我编写了一个后台工作程序来使进程运行asynchronously
。当每一行都被clikced时,会创建一个backgroundworker
的实例并完成该过程。在该更新期间,用户将选择网格的第二行并更新该值。所以这将创建另一个实例,该过程将在后台运行。
现在,如果用户选择网格的第一行,则当更新过程都在运行时,应该会显示一条消息,显示“进程仍在运行”。
//代码:
'点击事件
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");
}
}
如何访问先前创建的backgroundworker实例并检查进程状态并显示该等内容?
注意:可能有很多进程同时运行,因此我应该可以访问任何进程。
这可能吗?
答案 0 :(得分:2)
您可以在BackgrounWorker
中存储您创建的任何List
以随时引用它们,但也可以创建任务Queue
并存储任何待处理的进程,这样您就可以了任何时候只有一个BackgroundWorker
。
创建一个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
并运行存储的下一个任务。
答案 1 :(得分:1)
您可以使用Tag
的{{1}}属性:
DataGridViewRow
所以你可以访问它。
答案 2 :(得分:1)
如果你使用的是.NET 4.5 ,我建议使用Async / Await而不是Background线程来解决你的问题,因为它的编程风格简单有效,如下所示:
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
作为网格行的行标识符。
希望有所帮助。
答案 3 :(得分: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();
}
}