2016-02-08 33 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