我有一个创建BackgroundWorker的表单。然后,工作人员执行一些工作,并在报告忙时将ReportProgress发送回UI。然后我将这些消息记录到UI。 ReportProgress由线程中的一个方法完成,我称之为“Notify”。
但是,在线程中,我调用静态类来执行文件访问类型的工作。那个静态类还需要报告进度...所以我需要调用调用静态类的线程类的Notify方法 - 但是,我无法访问调用类中的方法。
因此,UI创建了线程......并且线程使用了一个类,但是我需要从静态类中调用类中的Notify方法。我怎么能这样做?
这是我的尝试。我的想法是尝试使用委托......但是,我仍然坚持使用委托。 :)
在我的线程类中,我有一个方法:
public void Notify(string message, Constants.ErrorLevel errorLevel)
{
var su = new StatusUpdate {StatusMessage = message, ErrorLevel = 0};
_bw.ReportProgress(0, su);
}
这很有效。它可以很好地报告调用UI。
我现在在这个类中创建了一个委托:
public delegate bool NotificationsDelegate(object MessageHolder);
我已经将用于处理文件管理的静态类更改为非静态类,并且我希望在创建它时将该委托传递给文件管理器类:
public class FileManager
{
private readonly NotificationsDelegate _notifications;
public FileManager(NotificationsDelegate notifications)
{
_notifications = notifications;
}
private void SendMessageBack(string p, ConsoleColor consoleColor)
{
var su = new StatusUpdate {ErrorLevel = 0, StatusMessage = p};
_notifications(su);
}
所以,我创建它,并传递Notification委托......然后在我的'SendMessageBack'方法中,希望调用委托(称为_notifications)。
但那就是我被困住的地方。委托尚未分配给notify方法。我是新手,所以猜测我的方式。但是,有人可以帮助我做到这一点吗?
答案 0 :(得分:1)
如果您打算在线程之间共享一个FileManager类实例,那么您每次调用它时都必须传入一个委托实例。如果在每个“线程类”中创建FileManager类的新实例,那么您可以在编写时将文件管理器委托给ctor。
public delegate void NotifyDelegate(string message, Constants.ErrorLevel errorLevel);
public class BackgroundWorker {
public BackgroundWorker() {
_fileMgr = new FileManager(Notify);
}
public void Notify(string message, Constants.ErrorLevel errorLevel) {
// do stuff
}
}
public class FileManager {
public FileManager(NotifyDelegate notification) {
_notification = notification;
}
public void SendMessageBack() {
_notification("foo", 0);
}
}
如果你想要,你可以使用lambda,并避免直接创建委托:
public class FileManager {
public FileManager(Action<string, Constants.ErrorLevel> notifyAction) {
_notification = notifyAction;
}
public void SendMessageBack() {
_notification("foo", 0);
}
}
public class BackgroundWorker {
public BackgroundWorker() {
_fileMgr = new FileManager((a, b) => Notify(a, b));
}
}
答案 1 :(得分:1)
我不确定我正在关注你正在做什么,但我会看一下基于事件的通知系统,用于从文件访问工作类中调用Notify
方法。我假设你的文件访问工作类被称为FileManager
并且它是一个实例类。
首先,创建一个自定义EventArg
类,以便在FileManager
类的通知中存储要中继的数据。在DoNotify
班级中使用此自定义FileManager
课程创建EventArg
个活动,并在您希望更新Notify
时调用该活动(在填充状态数据后)方法
当您实例化FileManager
对象时,订阅DoNotify
事件并在其处理程序中调用您的Notify
方法:
public class FileManager
{
public event EventHandler<NotifyEventArgs> DoNotify;
private void DoSomethingInterestingMethod() {
//...
// Let listeners know something interesting happened.
var doNotify = DoNotify;
if (doNotify != null) {
doNotify(this, new NotifyEventArgs(errorLevel, message));
}
//...
}
}
public class NotifyEventArgs : EventArgs
{
public NotifyEventArgs(int errorLevel, string statusMessage) {
ErrorLevel = errorLevel;
StatusMessage = statusMessage;
}
public int ErrorLevel { get; private set;}
public string StatusMessage { get; private set; }
}
然后在您的BackgroundWorker线程上(在DoWork
(?)中)创建一个或多个FileManager
个对象并订阅DoNotify
事件:
var fm = new FileManager();
fm.DoNotify += FileManager_Notify;
在DoNotify处理程序中调用Notify
方法:
void FileManager_Notify(object sender, NotifyEventArgs e) {
Notify(e.ErrorLevel, e.StatusMessage);
}
我不完全确定您的某些实施细节,所以我希望自己已经足够明确,让您评估这种方法并确定它是否适合您。