0

So I'm writing a program that will call a function CloseAppList() every ten seconds as a coroutine. And CloseAppList() will freeze my application for a few seconds everytime it's called. I discovered that it's when i'm trying to accessp.processname it freeze the program. I also print out the amount of processes is arround 350 which i don't think is much.

Here is my CloseAppList() function:

Process[] processes = Process.GetProcesses ();
string pName = "";
foreach (Process p in processes) {
    try{
        pName = p.ProcessName;
    }catch{
    }
}
yield return null;

I'm very confused by how it would freeze my application. Any suggestions would be appreciated.

libra
  • 673
  • 1
  • 10
  • 30
  • How are you calling the `CloseAppList()` function? You need to also comment out some of the codes in that function from bottom to up until you find what is causing the freeze then you put that in your question. – Programmer Mar 19 '17 at 12:59
  • @Programmer I called it as coroutine from another 10secupdate coroutine which calls it every 10 seconds. Yes, I remove most of the codes from my original function and figured out whenever I use p.ProcessName it freezes. – libra Mar 19 '17 at 13:13

1 Answers1

2

I did notice about 1 or 2 frame-rate drop when pName = p.ProcessName; is present. This is likely the result of new string objects being created in a loop. The freeze amount happens depends on the size of the running processes.

My suggestion is to move that piece of code into a Thread. In this case, a Thread pool is fine. Use coroutine for the timer that requires you to wait for 10 seconds. Make sure to include using System.Threading; at the top.

No freezing after I did this.

void Start()
{
    StartCoroutine(timedCaller());
}


IEnumerator timedCaller()
{
    WaitForSeconds waitTime = new WaitForSeconds(10);
    while (true)
    {
        //Call CloseAppList in another Thread
        ThreadPool.QueueUserWorkItem(new WaitCallback(CloseAppList));
        //Wait for 10 seconds
        yield return waitTime;
    }
}

void CloseAppList(object state)
{
    Process[] processes = Process.GetProcesses();
    string pName = "";
    foreach (Process p in processes)
    {
        try
        {
            pName = p.ProcessName;
        }
        catch
        {
        }
    }
}

Note:

The CloseAppList function will be called in a new Thread which means that you can't call Unity's API from this function. If you need to call Unity API from this function(another Thread), take a look at this answer.

Community
  • 1
  • 1
Programmer
  • 121,791
  • 22
  • 236
  • 328
  • Thank you very much, worked perfectly ! Although theres one point i don't understand. Why did you mention "This is likely the result of new string objects being created in a loop", i think i put the declaration of the string in front of foreach loop? – libra Mar 19 '17 at 17:50
  • I doesn't matter. Strings are immutable. They are not like strings in C++. New string is created when you do that. That's why there is something called `StringBuilder` in C#. I think that you should read more about strings in C#. – Programmer Mar 19 '17 at 22:44