静态类/对象?如何处置

时间:2016-02-08 08:37:41

标签: c#

我真的和OOP打交道。我想在我的附加课程中开始一个过程。这个过程是一个shell,我需要从severel表单和类访问这个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");
    }

}

My 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. 我退出表格课后如何处理和关闭我的流程?

3 个答案:

答案 0 :(得分:2)

1:你不需要静态类。你想要一个SINGLETON - 这是一个只有一个实例的类。通常使用静态属性访问它。最简单的方法就是这样:

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

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

访问是通过:

A.Instance

2:你没有。流程不会被处理掉。您退出不是后台线程的最后一个线程,然后该过程结束。否则你杀​​了它,如果必须从外面“有效”完成。

答案 1 :(得分:0)

在Form类的构造函数中移动ADBShell初始化。因此,此对象将一直存在,直到Form不退出并按进程释放资源,确保在ADBShell类中调用Process.close()(在析构函数中或实现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;

答案 2 :(得分: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;
        }
    }

}

<强>更新

感谢您的帮助我解决了我的问题,现在ADB的运行速度更快,而不是每次新流程都启动。

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