我有一个.Net 4.0类,它有一个自定义事件处理程序(StatusChanged
)。我试图通过一个线程消耗这个类。我没有使用BackgroundWorker
的奢侈,因为我使用的库不支持多线程单元状态。
StatusChanged
委托中的一个参数是字符串。
在UI中,单击按钮可初始化使用我的类的线程。
我正在努力使它成为一个UI控件(WPF)在StatusChanged
事件触发时更新为StatusChanged
字符串参数。我的理解是Dispatcher.Invoke
可以做到这一点,但我没有运气弄清楚如何将字符串拉出来。
基本上,我试图获得相当于BackgroundWorker.ProgressChanged
(ProgressChangedEventArgument.UserState
)。
这是一些缩小的代码,用于演示我的目标:
带有事件处理程序的类:
public class MyClass
{
public event EventHandler StatusChanged;
private void alertStatus(string message)
{
if(StatusChanged == null)
return;
this.StatusChanged(message, new EventArgs());
}
public void DoStuff()
{
///Do Stuff 1
alertStatus("Done with stuff #1");
///Do Stuff 2
alertStatus("Done with stuff #2");
}
}
所以按钮的.Click事件会做这样的事情:
private void buttonClicked(object sender, EventArgs e)
{
Thread t = new Thread(doWork);
t.Start();
}
private void doWork()
{
MyClass class = new MyClass();
class.StatusChanged += ...
class.DoStuff();
///As StatusChanged fires within MyClass, a UI Textbox would get updated
}
答案 0 :(得分:2)
使用lambda表达式最简单:
private void doWork()
{
// Name changed to avoid it being a keyword
MyClass clazz = new MyClass();
clazz.StatusChanged += (sender, args) => {
string message = (string) sender; // This is odd
Action action = () => textBox.Text = message;
Dispatcher.Invoke(action);
};
clazz.DoStuff();
}
使用字符串作为事件的发送者是非常奇怪的 - 最好使用EventArgs
的子类,并使其存储消息 - 然后使您的事件使用EventHandler<T>
代替仅EventHandler
。
上面的代码有点令人困惑,因为你用一个委托订阅事件,然后将另一个委托给Dispatcher.Invoke
- 因此两个lambda表达式(一个在另一个内)。您总是可以使用方法组,至少对于外部方法组:
private void doWork()
{
// Name changed to avoid it being a keyword
MyClass clazz = new MyClass();
clazz.StatusChanged += HandleStatusChange;
clazz.DoStuff();
}
private void HandleStatusChange(object sender, EventArgs e)
{
string message = (string) sender; // This is odd
Action action = () => textBox.Text = message;
Dispatcher.Invoke(action);
}