让我说我有任务1:
private void Task1()
{
//Here is some Code, could be any "longer" Task -
//For Example: Grab all words from a .txt File and fill in a List<String>
}
然后我还有另一个任务2:
private void Task2(string word)
{
//So lets say theres a Label on my WinForm..
//Now While Task1 is grabbing the words, Task2 should fill a Label
//with the added 'word' (parameter) - (Task2 will be called from Task1
}
实际上我不知道如何使这成为可能,或者最好的方式。在UI上,我应该能够看到Label.Text
更改(每个单词)..所以我需要制作第二个线程?我怎么能这样做?也许有人可以帮助我,欢呼
更新
我现在尝试使用Backgroundworker,但似乎有些错误......它实际上不起作用,表单上没有任何反应
代码:
public void CreateAndSaveAMatch(DateTime date) //That method is being called several times
{
//HERE IS CODE, WHICH CREATES AND SAVES A MATCH
// Start the asynchronous operation.
backgroundWorker1.RunWorkerAsync(date);
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
backgroundWorker1.ReportProgress(0, Convert.ToDateTime(e.Argument).ToShortDateString());
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
label1.Text = (string)e.UserState; //here on the Label I would like to show the Date
}
答案 0 :(得分:2)
使用BackgroundWorker
报告第一项任务的进度。将此组件从工具箱拖到您的表单,并订阅DoWork
和ProgressChanged
个事件。同时将属性WorkerReportsProgress
设置为true
。然后异步启动第一个任务:
// this will execute code in `DoWork` event handler
backgroundWorker1.RunWorkerAsync();
下一步 - 使用userState
对象传递处理过的单词:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
// grab words in a loop and report progress
backgroundWorker1.ReportProgress(0, word);
}
最后一步 - 更新ProgressChanged
事件处理程序
void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
label1.Text += (string)e.UserState; // this is your grabbed word
}
答案 1 :(得分:2)
好的,试试吧。这是一个简单的示例,它将向您展示如何使用BackgroundWorker
解决您的问题。另请注意,还有许多其他解决方案。要使用此示例,请在仅包含按钮和标签的新项目中创建表单。另请注意,这是对其他答案的补充,这是正确的。
public partial class Form1 : Form
{
BackgroundWorker createAndSaveAMatchBGW;
public Form1()
{
InitializeComponent();
createAndSaveAMatchBGW = new BackgroundWorker();
createAndSaveAMatchBGW.DoWork += new DoWorkEventHandler(createAndSaveAMatchBGW_DoWork);
createAndSaveAMatchBGW.ProgressChanged += new ProgressChangedEventHandler(createAndSaveAMatchBGW_ProgressChanged);
createAndSaveAMatchBGW.RunWorkerCompleted += new RunWorkerCompletedEventHandler(createAndSaveAMatchBGW_RunWorkerCompleted);
createAndSaveAMatchBGW.WorkerReportsProgress = true;
}
private void button1_Click(object sender, EventArgs e)
{
createAndSaveAMatchBGW.RunWorkerAsync(DateTime.Now);
}
void createAndSaveAMatchBGW_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
MessageBox.Show("BackgroundWorker finished");
}
void createAndSaveAMatchBGW_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
label1.Text = ((DateTime)e.UserState).ToString("ss");
}
void createAndSaveAMatchBGW_DoWork(object sender, DoWorkEventArgs e)
{
//BackgroundWorker does something for a 10 seconds, each second it Reports
BackgroundWorker bgw = (BackgroundWorker)sender;
DateTime dt = (DateTime) e.Argument;
for (int i = 0; i < 10; i++)
{
Thread.Sleep(1000);
dt = dt.AddSeconds(1);
bgw.ReportProgress(0, dt);
}
}
}
如果您在执行时仅从CreateAndSave ...方法报告一次,那么您可以使用此代码:
BackgroundWorker createAndSaveAMatchBGW;
public Form1()
{
InitializeComponent();
createAndSaveAMatchBGW = new BackgroundWorker();
createAndSaveAMatchBGW.DoWork += new DoWorkEventHandler(createAndSaveAMatchBGW_DoWork);
createAndSaveAMatchBGW.RunWorkerCompleted += new RunWorkerCompletedEventHandler(createAndSaveAMatchBGW_RunWorkerCompleted);
}
private void button1_Click(object sender, EventArgs e)
{
createAndSaveAMatchBGW.RunWorkerAsync(DateTime.Now);
}
void createAndSaveAMatchBGW_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
label1.Text = ((DateTime)e.Result).ToString();
}
void createAndSaveAMatchBGW_DoWork(object sender, DoWorkEventArgs e)
{
DateTime dt = (DateTime) e.Argument;
//you do something with your DateTime
dt = dt.AddDays(10);
e.Result = dt;
}
答案 2 :(得分:1)
实现此类事情的最简单方法是使用BackgroundWorker。
http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx
BackgroundWorker自动处理线程编组并提供允许您更新UI的事件。事件处理程序在UI线程上运行。
您在Task1中执行的操作可以移动到BackgroundWorker中,您建议在Task2中执行的UI更新实际上可以响应来自BackgroundWorker的进度事件。
ProgressChangedEventArgs提供可以保存当前单词的用户定义数据。
然而,如果你打算显示你加载的每个单词,Winforms(实际上几乎任何UI)都无法跟上一个单独的CPU线程只是加载文件中的单词。
答案 3 :(得分:0)
Task1
可以在一个单独的线程上启动。
除非执行一些复杂的逻辑来更新TextBox,否则实际上不需要Task2
。您真正需要做的是使用TextBox.Invoke()
从Task1
调用UI线程上的更新。