2013-04-18 123 views
0

我有一個創建BackgroundWorker的表單。然後,工作人員會做一些工作,並在ReportProgress忙時將消息發送回UI。然後我將這些消息記錄到用戶界面。 ReportProgress由線程中的單個方法完成,我稱之爲「通知」。調用常用方法的類 - 委託?

但是,在線程內,我調用靜態類來做文件訪問類型的工作。這個靜態類也需要報告進度......所以我需要調用線程類的Notify方法來調用靜態類 - 但是,我無法訪問調用類中的方法。

所以,UI創建線程...並且線程使用一個類,但是我需要從靜態類調用類中的Notify方法。我怎樣才能做到這一點?

這是我的嘗試。這個想法是嘗試使用委託...但是,我堅持實際使用委託。 :)

在我的線程類,我有一個方法:

public void Notify(string message, Constants.ErrorLevel errorLevel) 
{ 
    var su = new StatusUpdate {StatusMessage = message, ErrorLevel = 0}; 
    _bw.ReportProgress(0, su); 
} 

這是工作。它可以很好地向調用用戶界面報告。

我現在在這個類中創建一個委託:

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); 
} 

所以,我創建它,並通過通知委託...然後在我的「SendMessageBack」的方法,希望能夠調用該委託(被稱爲_notifications)。

但這就是我卡住的地方。委託尚未分配給通知方法。我對事件很陌生,所以猜測我的方式。但是,有人可以幫我解決這個問題嗎?

+0

將BackgroundWorker傳遞給靜態類中的方法,以便它可以調用ReportProgress? – dtb 2013-04-18 04:12:20

+0

我在想這個,但是每次使用靜態方法時,我都必須將bw對象添加到每個調用中? – Craig 2013-04-18 04:17:57

回答

1

如果您計劃在線程之間共享FileManager類的一個實例,那麼您每次調用它時都必須傳入一個委託實例。如果您在每個「線程類」中創建一個FileManager類的新實例,那麼您可以按照書面方式向FileManager中的委託人提供該委託。

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); 
    } 
} 

如果你願意,你可以只使用拉姆達的,並避免直接創建代表:

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

我不能肯定我跟着你在做什麼,但我會帶請查看基於事件的通知系統,以便從您的文件訪問工作班級調用Notify方法。我假設你的文件訪問工作類叫做FileManager,它是一個實例類。

首先,創建一個自定義EventArg類,用於存儲要在FileManager類中發出的通知中要傳遞的數據。在FileManager類中使用此類定製EventArg類創建一個DoNotify事件,並在您想要更新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); 
} 

我不能完全肯定你的一些實施細節,所以我希望我做我自己清楚,足以讓您評估這一做法,並決定它是否適合你。