【发布时间】:2015-04-20 04:39:16
【问题描述】:
我实际上正在学习(艰难的方式)c#,并且已经为一个问题奋斗了好几天:
我正在使用 WPF (dotNet 4.0) 编写我的第一个 c# 应用程序。当我单击一个按钮时,将使用一个 BackgroundWorker 线程并从外部类调用一个方法,这样我的 UI 就不会冻结 -> 我的方法按预期运行。
然后我尝试从外部类更新 ListView 控件以获取某种进度(文本),但我失败了。
我了解我需要使用委托和调度程序来更新我的控件。
我尝试使用此处提供的解决方案 How to update UI from another thread running in another class 。 (由于我的代表率低,我无法对此发表评论)并且我错过了这个难题的某些部分。
YourEventArgs(status) 指的是什么?当我的方法在 BGW 中运行时,我无法触发事件并将内容传递回我的 UI。
到目前为止,我有这段代码(从答案更新):
namespace AppMain
{
public partial class MainWindow
{
BackgroundWorker AppWorker = new BackgroundWorker();
public MainWindow()
{
InitializeComponent();
AppWorker.WorkerSupportsCancellation = true;
AppWorker.DoWork += AppWorker_DoWork;
AppWorker.RunWorkerCompleted += AppWorker_RunWorkerCompleted;
}
private void btnLoad_Click(object sender, RoutedEventArgs e)
{
lstTest.Items.Add("Processing data...");
AppWorker.RunWorkerAsync();
}
public void AppWorker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
SetXmlData xml = new SetXmlData();
xml.ProgressUpdate += (s, evt) =>
{
Dispatcher.BeginInvoke((Action)(() =>
{
lstTest.Items.Add("this is a test : " + evt.myData); //how to retrieve the myData property from evt ?
}));
};
xml.FlushData();
}
public void AppWorker_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
{
if (!(e.Cancelled))
{
lstTest.Items.Add("Done");
}
else
{
MessageBox.Show("Cancelled");
}
}
}
}
SetXmlData.cs
namespace AppMain
{
public class SetXmlData
{
public event EventHandler ProgressUpdate;
//update method
public void update(object input)
{
if (ProgressUpdate != null)
ProgressUpdate(this, new YourEventArgs { myData = (string)input });
}
//calculation method
public void FlushData()
{
MessageBox.Show("this is a test !");
update("test");
}
}
public class YourEventArgs : EventArgs
{
public string myData { get; set; }
}
}
感谢您的帮助。
【问题讨论】:
-
如果您在 .net 4.0 中有任务,为什么要使用 BGW,可以由当前同步上下文提供以在其中执行?
-
我一开始是在使用这个,但后来为了 ReportProgress 功能转移到了 BGW,最后你是对的,当我解决这个问题时,我会切换回 Task 也不是更好。
标签: c# wpf multithreading events delegates