Shazter February 2016

Static class / Object? How to dispose

i'm really struggeling with OOP. I would like to start a process in my additional class. The process is a shell and I need to access this shell from severel forms and classes to write the commands and to receive the output. I use events to get the data. Here is my class for the process.

My class for the

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 class looks like

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

        privat        

Answers


TomTom February 2016

1: You do not want a static class. You want a SINGLETON - that is a class that has only one instance. This is normally accessed using a static property. At the easiest way this works like this:

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

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

Access is via:

A.Instance

2: You do not. Processes do not get disposed. You exit the last thread that is not a background thread then the process ends. Otherwise you kill it, if that has to be done "In force" from the outside.


Viru February 2016

Move the ADBShell intialization in constructor of Form class. So this object will live till Form is not exited and to release resources by process make sure you call Process.close() in ADBShell class (Either in destructor or implement a 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 Process like this by adding Destructor

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

or implement Dispose method of IDisposable

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

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

Updated singleton class

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


Shazter February 2016

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

}

Update

Thank you with your helps I solved my problems and now the ADB runs much faster instead of start everytime a 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.Writ 

Post Status

Asked in February 2016
Viewed 2,164 times
Voted 11
Answered 3 times

Search




Leave an answer