Friday, November 30, 2012

Monitor process memory and CPU usage in C#

There are relevant libraries to monitor process memory and CPU usage.

[1] Process Class
[2] How to get CPU usage of processes and threads
[3] Pushing the Limits of Windows: Physical Memory

It's a little confusing with multiple functions on memory usage, but WorkingSet64() is one that can be used.

Multi-threading with C#

Ok, I worked on multi-threaded applications in C# in the past. Now I'm back to do something again.

Some notes:

1. Below 2 are the same for C# 2.0 and after, ThreadStart can be omitted (but can be useful say when you want to start a group of functions):

    1) Thread newThread = new Thread(new ThreadStart(this.checkProcesses)); 
    2) Thread newThread = new Thread(this.checkProcesses); 

2. The new thread by default is not a background process, which means when the GUI exits, it continues to run in the background. If you set it as a background process, then GUI exit will cause it to exit as well (usually this is desired):

    newThread.IsBackground = true; // usually desired.

3. Access of GUI control needs special handling using Invoke() method:

    delegate void SetTextCallback(string a, string b);
    private void setMsg(string a, string b) {
        if (this.textBox1.InvokeRequired) {
            SetTextCallback d = new SetTextCallback(setMsg);
            this.Invoke(d, new object[] { s, b });
        }
        else { this.textBox1.Text = a + b; }
    }

Then call the setMsg method in the thread method: this.setMsg("hello, ", "world");

Ways of using multi-threading:

    // Method 1. basic method.
    Thread newThread = new Thread(this.checkProcesses); 
    newThread.IsBackground = true; 
    newThread.Start();

    // Method 2. use BackgroundWorker. 

References:

[1] Multi-process: http://msdn.microsoft.com/en-us/library/6x4c42hc.aspx
[2] Multiple process, access form control: http://msdn.microsoft.com/en-us/library/ms171728%28v=vs.80%29.aspx
[3] Background worker: http://stackoverflow.com/questions/363377/c-sharp-how-do-i-run-a-simple-bit-of-code-in-a-new-thread

Monday, November 19, 2012

Recover from winlogon failure

Ok, I got this blue screen error when booting my Dell/XP Professional computer after a shutdown with error with message:

STOP:  c000021a {Fatal System Error}
The Windows Logon Process system process terminated unexpectedly with a status of 
0xc0000005 (0x00000000 0x00000000).
THe system has been shut down.

There is no way to log in no matter what I do: not in safe mode, not in previous good configuration, not using the original XP Professional installation disk from Dell.

A good suggestion I received after searching on line is here.

It says my c:\windows\system32\winlogon.exe file is corrupted and I need to replace it with a good one.

Since I was not able to get in the system even with the original Dell installation CD, I tried to use Hiren's BootCD and it worked! I was able to back up my important files on C drive now.

I followed instruction by replacing c:\windows\system32\winlogon.exe with c:\windows\system32\dllcache\winlogon.exe, but it got the same error. I searched my computer and found C:\WINDOWS\SoftwareDistribution\Download\9866fb57abdc0ea2f5d4e132d055ba4e\winlogon.exe, then used this for replacement. It worked and now I can log in!

But I still see nothing after logging in, which means c:\windows\explorer.exe is also corrupted. Again, replace it with c:\windows\system32\dllcache\winlogon.exe did not work, but C:\WINDOWS\SoftwareDistribution\Download\9866fb57abdc0ea2f5d4e132d055ba4e\explorer.exe worked!

So now, one day later, my computer is recovered. I'm glad I didn't have to reinstall it.

Tuesday, November 13, 2012

DOS command

[1] Remove a non-empty folder (see Remove a Directory and All Subdirectories): RMDIR c:\blah /s /q
/s - remove directory when it's not empty.
/q - quiet mode, no prompt for yes/no.

[2] in vbs file, call a dos command, may have error "file not found", adding "CMD /C" before the command will remove the error: objShell.Exec("cmd /C rmdir folder_to_remove /S /Q")

Friday, October 5, 2012

"using" keyword in C#, and large file processing

1. Using

The "using" keywork in C# is used to either import a library, or to cause a local variable to be disposed immediately after use.

To design a class that can be used in the using(...) clause, the class needs to implemented the IDisposable interface. This mostly means to implement the Dispose() and Dispose(boolean) methods, and deallocate local resources in the Dispose(boolean) method. See http://msdn.microsoft.com/en-us/library/system.idisposable.aspx.

2. Processing large data file

Processing of large data file may run out of memory if everything is done inside memory, for example, XmlSerializer may do this. The solution is to do the processing chunk by chunk (e.g., line by line, or block by block if no line separator).

For example, processing a file of 13GB will exhaust almost 16GB memory, causes the machine to hang for 30 minutes and fail. Using line by line processing, it takes 15 minutes and works successfully. Of course, for line by line processing, output can use buffering to avoid too many IO which also can be slow.

Another example is when reading a large file, in C/C++, read by line is much faster than read by char. But, for a binary file, you will not be able to read by line.

So processing large file requires careful handling of memory and IO.

Also, when a file is large, for example the 13GB file which does not contain any new line character (so read by line does not work), it can't be open by any common editor on windows including notepad, wordpad or VS.NET studio; it also can't be open on linux by vi. Well, when use vi to open it, it waits and seems there is never an end to the waiting. Search google shows that vi will have difficulty opening file with more than 9070000 character or file of size 2GB. Also for openning large file under 2GB, it will be faster for vi by disabling swap file, syntax parsing or undo history, see How to open big size file using vi editor or Faster loading of large files.

Use Perl to open the file also waits for ever. Actually using Perl it should also work if read as byte stream. Using C or Java to read as byte stream it works immediately.

Below is Java code to read as a byte stream:

import java.lang.*;
import java.io.*;

public class readByteFile {
  public static void main(String[] args) {
    InputStream is = null;
    ByteArrayOutputStream os = null;

    try  {
      File f = new File("filename");
      byte[] b = new byte[100];      // byte buffer.
      is = new FileInputStream(f);
      os = new ByteArrayOutputStream();

      int read = 0;
      int len = 0;
      while ( (read = is.read(b)) != -1 ) {
        os.write(b, 0, read);
        System.out.print(new String(b));
        len += read;
        if (len > 1000) break;
      }

      System.out.println(new String(b));
    } catch (Exception e) {

    } finally {
      try { if (os != null) os.close(); } catch (IOException e) {}
      try { if (is != null) is.close(); } catch (IOException e) {}
    }
  }
}
Or read in C using fgetc():
#include 

int main() {
  FILE * f = fopen("filename", "r");
  char ch;
  long ct = 0;      // char count.
  long line_ct = 0; // line count.

  if (f != NULL) {
    while (1) {
      ch = fgetc(f);
      ct ++;
      if (ch == '\r' || ch == '\n') line_ct ++;

      if (ch == EOF) break;

      putchar(ch);

      if (ct > 1000) break;
      if (line_ct > 5) break;
    }
  }
  printf("\n");
  fclose(f);
  return 0;
}

Blog Archive

Followers