2014-10-22 119 views
0

我有一個c#windows窗體mp3播放器應用程序。我有我的資源文件夾和一個單獨的「MyAudio」靜態它處理喜歡玩和提高音量等 從我的表中的所有音頻相關工作類的音頻文件,我只是用調用play方法:c#靜態或非靜態類

MyAudio.Play(track); 

在MyAudio類,我聲明爲對象的WindowsMediaPlayer:

private static WindowsMediaPlayer obj=new WindowsMediaPlayer(); 

我的問題是,在效率和更少的內存使用方面,是它更好地申報MyAudio類爲靜態或非靜態的?在表單中創建MyAudio類的對象,然後調用方法或直接使用類名調用是否明智? 將實例變量聲明爲靜態也是很好的做法嗎?

+2

你的問題有點寬泛。請記住,在使用靜態類時,該對象將在應用程序的整個生命週期內存活。如果你在裏面分配一個大的資源,它將一直存在。另外,'static'類往往不易測試。 – 2014-10-22 04:52:09

+0

因此,爲了減少內存使用量,我應該將它們定義爲非靜態,並且每次只創建對象? – Chuker 2014-10-22 04:58:55

+0

這是我爲這個特殊情況採取的方法。 – 2014-10-22 04:59:52

回答

2

你的問題確實是廣泛的,但也有,你可以照顧,當你在設計一個類幾個設計原則:

  • 我需要的對象,並在整個應用程序生命週期的狀態
  • 我需要保持類變量的狀態,以備將來使用
  • 我需要多線程或在時間
  • 我需要去耦元件在未來和其他使用的任何點並行化應用像基於Ajax的場景w eb場景

在這種情況下,重要的事情是您需要維護應用程序生命週期的狀態,並且應用程序環境的內存使用量很好,因爲初始化後您將能夠獲得所有來自內存的數據並且不需要像數據庫那樣查詢源。但是,這對於需要初始化一次並在應用程序的其餘部分中作爲靜態信息讀取的情況非常有用。如果你打算重新查詢信息,那麼使用靜態類型的部分目的將會丟失

假設將來你需要並行化你的代碼以提高性能,那麼靜態將會困擾你,因爲它將在線程之間共享,並且總是需要像鎖,互斥體這樣的同步構造,這會將所有線程串行化,因此目的將會丟失。在Web/Ajax場景中會發生同樣的情況,並且您的靜態組件無法處理多個並行請求,並且直到和未同步時都會損壞。這裏每個線程的實例變量是一個福音,因爲他們做任務/數據並行化,而不需要鎖,互斥體

在我的理解中,靜態是一種方便,許多程序員誤用,避免實例變量和隨意使用理解其含義。從GC的角度來看,它不能收集靜態變量,所以應用程序的工作集合總是會增加,直到它穩定下來並且不會減少,除非程序明確發佈,這對任何應用程序都是不利的,除非我們存儲數據以避免網絡數據庫調用。

理想的設計會建議始終使用實例類,該實例類會被創建,完成其工作並被釋放,而不會留在周圍。如果有信息需要從一個函數傳遞到另一個函數(如從Play到Pause到Stop),那麼可以將該數據保存到一個靜態變量並以線程安全方式進行修改,這是一個更好的方法

如果我們只是舉一個例子,因爲它是一個Windows窗體,它執行像Play這樣的操作,那麼static會很好,因爲它是一個在系統上運行的可執行文件,但對於測試來說,想象一下您啓動多個實例通過按下不同的操作,然後他們都會訪問相同的靜態對象,你可能會遇到一個腐敗問題,實際上爲了解決這種情況,你甚至可以選擇你的班級是單身人士,在給定的時間內,內存中不能存在多於一個實例,就像它發生在Yahoo Messenger上一樣,不管你多少次都是這樣k,總是有相同的實例出現。

+0

謝謝這麼多:) – Chuker 2014-10-22 05:54:51

0

沒有靜態實例變量。然而,如果靜態成員與類的特定實例無關,則最好定義靜態成員。

+0

好的。因爲我的WindowsMediaPlayer對象只是在MyAudio類中使用,所以我會聲明它是非靜態的。 – Chuker 2014-10-22 04:59:59

+0

問題是總是需要多少個實例...我想你需要一個......使之成爲靜態 – 2014-10-22 05:11:34

+0

而靜態方法無法達到實例字段...至少不是直接 – 2014-10-22 05:13:09