2016-02-08 32 views
0

我真的非常喜歡OOP。我想在我的附加課程中開始一個流程。這個過程是一個shell,我需要從嚴重的形式和類訪問這個shell來編寫命令並接收輸出。我使用事件來獲取數據。這是我的課程。靜態類/對象?如何處置

我對

public class ADBShell 
{ 

    public static string output = String.Empty; 
    public static Process adbshell = new Process(); 



    public void Start_ADBShell() 
    { 
     if (adbshell != null && !adbshell.HasExited) 
      return; 

     adbshell = new Process(); 
     adbshell.StartInfo.UseShellExecute = false; 
     adbshell.StartInfo.FileName = @"D:\adb\adb.exe"; 
     adbshell.StartInfo.Arguments = "shell"; 
     adbshell.StartInfo.RedirectStandardOutput = true; 
     adbshell.StartInfo.RedirectStandardInput = true; 
     //adb.StartInfo.RedirectStandardError = true; 
     adbshell.EnableRaisingEvents = true; 
     adbshell.StartInfo.CreateNoWindow = true; 
     //adb.ErrorDataReceived += new DataReceivedEventHandler(adb_ErrorDataReceived); 
     adbshell.OutputDataReceived += new DataReceivedEventHandler(adbshell_OutputDataReceived); 


     try { var started = adbshell.Start(); } 
     catch (Exception ex) 
     { 


      Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace); 
     } 

     //adb.BeginErrorReadLine(); 
     adbshell.BeginOutputReadLine(); 

    } 

    void adbshell_OutputDataReceived(object sender, DataReceivedEventArgs e) 
    { 

     output += (e.Data) + Environment.NewLine; 

    } 

    public void press_touch(string x, string y) 
    { 
     adbshell.StandardInput.WriteLine("input tap " + String.Format("{0} {1}", x, y)); 
     Debug.WriteLine("pressed"); 
    } 

類}

我的Form類看起來像

public partial class Form1 : Form 
{ 
     private bool _record; 
     private bool _selecting; 

     private Rectangle _selection; 

     //--------------------------------------------------------------------- 
     public Form1() 
     { 
      InitializeComponent(); 

     } 

     //--------------------------------------------------------------------- 
private void Form1_Load(object sender, System.EventArgs e) 
{ 
    ADBShell adbshell = new ADBShell(); 
    adbshell.Start_ADBShell(); 

} 

每次我必須做出一個新的對象在我的方法,但我不希望創建每次都有新的對象。我想讓對象每次訪問一次,並訪問同一個對象。我不想製作絲毫過程。我只需要進程,每次發送和接收數據到這個進程。

  1. 我必須做一個靜態類嗎?
  2. 如何在我退出Form類後處理並關閉進程?
+0

1。不,只是傳遞對象。 2.在處理表單時處理'Process'。 –

+0

這裏是你的單例 - 「公共類ADBShell {私有靜態ADBShell實例{get; } = new ADBShell();私人ADBShell(){}}' – Enigmativity

回答

2

1:你不想要一個靜態類。你想要一個SINGLETON - 這是一個只有一個實例的類。這通常使用靜態屬性進行訪問。在最簡單的方法這是這樣的:

public class A() { 
private A() {} 

public static A Instance {get; } = new A(); 
} 

訪問是通過:

A.Instance 

2:你不知道。流程不會被處置。您退出最後一個不是後臺線程的線程,然後進程結束。否則,你會殺死它,如果這必須從外面「有效」完成。

+0

我也推薦閱讀由Jon Skeet撰寫的有關單身人士的文章:http://csharpindepth.com/Articles/General/Singleton.aspx –

+0

感謝您的快速回復。我會嘗試與單身人士,但首先我必須閱讀一些關於單身人士的例子和指南。 – Shazter

+0

@TomTom你爲什麼說流程沒有被廢棄。如果我通過Dispose正確理解,則意味着釋放由進程持有的資源。 Process類具有Close方法,根據MSDN它釋放與Process相關的資源。 – Viru

0

在Form類的構造函數中移動ADBShell初始化。所以,這個對象將活到形式不退出,並通過過程中加入以釋放資源確保您撥打Process.close()在ADBShell類(無論是在析構函數或者實現了IDisposable)

public partial class Form1 : Form 
    { 
      private bool _record; 
      private bool _selecting; 
     ADBShell adbshell; 
      private Rectangle _selection; 

      //--------------------------------------------------------------------- 
      public Form1() 
      { 
       InitializeComponent(); 
       adbshell = new ADBShell(); 
      } 

      //--------------------------------------------------------------------- 
    private void Form1_Load(object sender, System.EventArgs e) 
    { 

     adbshell.Start_ADBShell(); 

    } 

Dipose過程是這樣析構函數

~ADBShell() 
{ 
    process.Close(); 
} 

或實現IDisposable

的Dispose方法
Class ABDShell : IDisposable 
{ 
    ... 
    ... 
public void Dispose() 
    { 
     Dispose(true); 
     GC.SuppressFinalize(this); 
    } 

    protected virtual void Dispose(bool disposing) 
    { 
     if (disposing) 
     { 
      process.Close(); 
     } 
    } 
} 

更新單身類

sealed class ADBShell 
{ 

    public static string output = String.Empty; 

    private ABDShell _instance; 
    private Process _processInstance; 

    // Note: constructor is 'private' 

    private ADBShell() 
    { 


    } 

    public Process ProcessInstance 
    { 
      if(_processInstance==null) 
      _processInstance = new Process(); 
      get _processInstance ; 
    } 

    public static ADBShell Instance 
    { 
     get 
     { 

      if (_instance == null) 
      { 

       _instance = new ABDShell(); 
      } 
      return _instance; 
     } 
    } 
} 
從表

現在只要做到這一點

Process process = ABDShell.Instance.ProcessInstance; 
+0

如果我這樣做了,那麼這個過程在我的其他課堂上是不知道的。意思是我不能在另一個類中使用我的方法,因爲這個對象是未知的。 – Shazter

+0

@Shazter我明白你的第二個問題,你需要單獨的Process類的每個Form的實例...如果不是這樣的話,那麼提及使用單例模式的方式去其他答案... – Viru

+0

好吧,現在我明白了。我做了一個單例類,我將使用Interface IDisposable在我的主應用程序關閉後結束該過程。 – Shazter

0
// Sealed class makes sure it is not inherited. If inheritance required, go to Abstract Pattern. 
class ADBShell 
{ 
    //public static property used to expose Singleton instance. 
    public static ADBShell Instance; 



    // private constructor 
    private ADBShell() { } 

    public static ADBShell getInstance() 
    { 
     if (Instance == null) 
     { 
      Instance = new Process; 
     } 
    } 

} 

更新

謝謝你幫助我解決我的問題,現在亞洲開發銀行運行開始,每次要快得多,而不是一個新的過程。

public class ADBShell 
{ 
    private static ADBShell instance; 
    //private List<Employee> employeeList = null; 
    private Process shell = null; 
    private StreamWriter myWriter = null; 
    private static readonly object syncRoot = new object(); 

    private ADBShell() 
    { 
     if (shell == null) 
     { 
      shell = new Process(); 
      shell.StartInfo.FileName = (@"D:\ADB\ADB.exe"); 
      shell.StartInfo.Arguments = "shell"; 
      shell.StartInfo.RedirectStandardInput = true; 
      shell.StartInfo.UseShellExecute = false; 
      shell.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; 
      shell.StartInfo.RedirectStandardOutput = true; 
      shell.StartInfo.CreateNoWindow = true; 
      shell.EnableRaisingEvents = true; 
      shell.OutputDataReceived += (sender, a) => Console.WriteLine(a.Data); 
      shell.Start(); 
      myWriter = shell.StandardInput; 
      shell.BeginOutputReadLine(); 



     } 
    } 

    public static ADBShell Instance() 
    { 
     if (instance == null) 
     { 
      lock (syncRoot) 
      { 
       if (instance == null) 
       { 
        instance = new ADBShell(); 
       } 

      } 



     } 
     return instance; 
    } 

    public void tap(int x, int y) 
    { 
     myWriter.WriteLine("input tap {0} {1}", x.ToString(), y.ToString()); 
     Thread.Sleep(10); 
    } 

    public void tap(string x, string y) 
    { 
     myWriter.WriteLine("input tap {0} {1}", x, y); 
     Thread.Sleep(10); 

    } 

    public void exit() 
    { 
     myWriter.WriteLine("exit"); 

    } 
    public void Close() 
    { 
     myWriter.WriteLine("exit"); 
     shell.WaitForExit(); 
     if (!shell.HasExited) 
     { 
      shell.Kill(); 
     } 


     shell.Close(); 
     shell.Dispose(); 
     myWriter.Close(); 
     myWriter.Dispose(); 
    } 
} 
+0

如果我嘗試這樣,然後我得到一個錯誤,這是不可能轉換過程到ADBShell。我想我不太瞭解單身人士,也許有人有一個簡短的暗示 – Shazter

+0

請停止回答你的問題。編輯你的問題。 – Enigmativity