Tuesday, November 1, 2011

Access command line arguments in C#

There are two common ways to read command line arguments in C#. First, you can override the Main method with an array of strings, which are command line arguments. For example, the following code loops through the command line arguments and print them on the console.




static void Main(string[] args)



{



foreach(string arg in args)



{



Console.WriteLine(arg);



}



Console.ReadLine();



}



You can do so using the Environment class, which has a static method called GetCommandLineArgs, which returns an array of strings containing the arguments. The following code reads the command line arguments using Environment.GetCommandLineArgs method.




foreach (string arg in Environment.GetCommandLineArgs())



{



Console.WriteLine(arg);



}

Tuesday, October 25, 2011

Run the application in admin mode

You'll want to modify the manifest that gets embedded in the program. Works on VS2008 + 2010: Project + Add New Item, select "Application Manifest File". Change the element to:

Adding a requestedExecutionLevel element to your manifest is only half the battle, you have to remember that UAC can be turned off, if it is, you have to perform the check the old school way and put up a error dialog if the user is not admin (Call IsInRole(WindowsBuiltInRole.Administrator) on your threads CurrentPrincipal)

http://msdn.microsoft.com/en-us/library/bb756948.aspx

Thursday, September 22, 2011

Friday, September 9, 2011

SQL server tips and tricks

Index and index with include for easy lookup
scan for problem and reindex it
dbcc showcontig('reli.tblTests')
dbcc showcontig('reli.tblTestLogs')
dbcc dbreindex ('reli.tblTests')
dbcc dbreindex('reli.tblTestLogs')

Tuesday, August 16, 2011

C++ Tips and tricks

if a variance is declared, it needed to be cleared before delete it to release memory

CComVariant varResult;


CComVariant* pvars = new CComVariant[2];

VariantClear(&varResult);


VariantClear(&pvars[0]);

VariantClear(&pvars[1]);

delete[] pvars;

// When using SysAllocString or AllocSysString to create a BSTR string the SysFreeString needs to be called to delete the allocated BSTR.
// If the BSTR resources are not freed it will remain in memory even when the method goes out of scope.
// For more information refer to http://msdn.microsoft.com/en-us/library/xda6xzx7(v=vs.71).aspx.   *ListOfTests = ::SysAllocString(strTests.AllocSysString()); should be
*ListOfTests = strTests.AllocSysString();

BSTR windowCaption = strCap.AllocSysString();


BSTR sTime = strTime.AllocSysString();

BSTR filter = strFilter.AllocSysString();

BSTR logText = strText.AllocSysString();Fire_OnPrintMsg (windowCaption, sTime, filter, logText);
::SysFreeString(windowCaption);

::SysFreeString(sTime);

::SysFreeString(filter);

::SysFreeString(logText);

Friday, June 24, 2011

command prompt tips

Windows7: whoami to display current user
net local group administrators to display a list of admins

check to see who logged in: qwinsta

ls -l to list files with details

tab to view a list of files or folders availabe

:: delete any aliases to x:


subst /d X:
:: make alias for QDART dir to x:

subst X: C:\work\


echo Build started at


time /T



:: delete any aliases to x:

subst /d X:



:: make alias for QDART dir to x:

subst X: %0\..\..\..\..



::set P4 port

set P4PORT=qctp404:1666



:: Some debugging

p4 set > X:\P4_SET.TXT

set > X:\DOS_SET.TXT



cd X:\HTE\QDART\QSPR3



set P4CLIENT=CRM_%BLD_ENV_BUILD_ID%%BLD_ENV_VER_NUM_COMPRESSED%

:: Some debugging after setting p4client

p4 set > X:\P4_SET1.TXT

set > X:\DOS_SET1.TXT

::HIVE projects

::Call Hive build to build Hive dlls

CALL QSPR3_HiveBuild_Ext_Release.cmd

::move the just built hive files to where the mergemodule code is expecting

mkdir QSPR\QSPRMergeModule\HiveRelease

copy /y qspr\kernels\hivecomkernel\bin\qspr_release\*.dll QSPR\QSPRMergeModule\HiveRelease

::also copy the MS files

copy /y QSPR\QSPRMergeModule\MicrosoftFiles\*.dll QSPR\QSPRMergeModule\HiveRelease



::CTS Projects

CALL QSPR3_CTSBuild_Ext_Release.cmd

::move the just built CTS files to the mergemodule code is expecting

mkdir QSPR\QSPRMergeModule\CTSRelease

copy /y qspr\kernels\CTSCOMKernel\Bin\CTSRelease\*.dll QSPR\QSPRMergeModule\CTSRelease



:: check out the msm



p4 sync -f //depot/HTE/QDART/MergeModules/QSPR3_MergeModule.msm

p4 edit -c default //depot/HTE/QDART/MergeModules/QSPR3_MergeModule.msm



::unlock interop files to build the QSPR Application

attrib -R "QSPR\Output\Bin\*.dll"



set path="C:\Program Files (x86)\Microsoft Visual Studio 8\Common7\IDE\";"C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\";%path%



devenv.exe "QSPR\QSPR_External.sln" /rebuild "Release" /project "QSPRMergeModule" /out QSPR3.1BuildLog.txt



::lock interop files back for Perforce to update

attrib +R "QSPR\Output\Bin\*.dll"



:: check the status of the build

set errCode=%ERRORLEVEL%



if not %errCode%==0 goto FAIL



::copy the merge module to QDART/mergemodules

copy /y QSPR\QSPRMergeModule\Release\QSPR3_MergeModule.msm ..\MergeModules

:: check in the merge module

p4 submit -d %BLD_ENV_BUILD_ID%_%BLD_ENV_VER_NUM_DOTTED% //depot/HTE/QDART/MergeModules/QSPR3_MergeModule.msm



:: check the status of the check-in

set errCode=%ERRORLEVEL%



if not %errCode%==0 goto FAIL



:: create the BuildProducts.txt file

echo .\HTE\QDART\QSPR3\QSPR\QSPRMergeModule\HiveRelease\HIVECOMKernel.dll > x:\BuildProducts.txt

echo .\HTE\QDART\QSPR3\QSPR\QSPRMergeModule\HiveRelease\HIVEEH.dll >> x:\BuildProducts.txt

echo .\HTE\QDART\QSPR3\QSPR\QSPRMergeModule\HiveRelease\HIVEK.dll >> x:\BuildProducts.txt

echo .\HTE\QDART\QSPR3\QSPR\QSPRMergeModule\HiveRelease\HIVEUIF.dll >> x:\BuildProducts.txt

echo .\HTE\QDART\QSPR3\QSPR\QSPRMergeModule\CTSRelease\COMKernel.dll >> x:\BuildProducts.txt

echo .\HTE\QDART\QSPR3\QSPR\QSPRMergeModule\CTSRelease\CTKernel.dll >> x:\BuildProducts.txt

echo .\HTE\QDART\QSPR3\QSPR\QSPRMergeModule\CTSRelease\Ctser.dll >> x:\BuildProducts.txt

echo .\HTE\QDART\QSPR3\QSPR\QSPRMergeModule\CTSRelease\Ctsui.dll >> x:\BuildProducts.txt

echo .\HTE\QDART\QSPR3\QSPR\QSPRMergeModule\Release\QSPR3_MergeModule.msm >> x:\BuildProducts.txt



:: Everything went well if you get here

subst /d X:

EXIT /B 0



:: something failed if you get here

:FAIL

p4 revert //depot/HTE/QDART/MergeModules/QSPR3_MergeModule.msm

subst /d X:

EXIT /B %errCode%



echo Build ended at

time /T

Thursday, June 16, 2011

Using queue in c#

Queue myCollection = new Queue();


lock(myCollection.SyncRoot)

{

foreach (object item in myCollection)

{

// Insert your code here.

}

}

Friday, May 6, 2011

COM

When dealing with com, need to releasemarshal when it's excel com, for perl, for c# that wrapper around to become com it doesn't start as a separate process, need some intialize and uninstalize

print "Uninitializing OLE \n";

Win32::OLE->Uninitialize();

Thursday, May 5, 2011

Good string tips

//convert list to comma separated string
string seperated = string.Join(",", yourList.ToArray());

Friday, April 29, 2011

Catch Exception in VS2010

I am under Visual Studio 2010 in a Windows Application Project with framework 4. So to achieve your need you right click on My Project Folder and click open. Under Application tab (the default one) click on the latest button View Application Events. This will create an ApplicationEvents class. Open it and copy paste this code :






Public Sub My_Startup(ByVal sender As Object, ByVal e As Microsoft.VisualBasic.ApplicationServices.StartupEventArgs) Handles Me.Startup



AddHandler AppDomain.CurrentDomain.UnhandledException, AddressOf CurrentDomain_UnhandledException

AddHandler System.Windows.Forms.Application.ThreadException, AddressOf UIThreadException



End Sub





Private Sub UIThreadException(ByVal sender As Object, ByVal ex As ThreadExceptionEventArgs)



Try



WriteErrorLog(ex.Exception)



Catch



Finally



End Try



End Sub



' Handle the UI exceptions by showing a dialog box, and asking the user whether

' or not they wish to abort execution.

' NOTE: This exception cannot be kept from terminating the application - it can only

' log the event, and inform the user about it.

Private Sub CurrentDomain_UnhandledException(ByVal sender As Object, ByVal e As System.UnhandledExceptionEventArgs)

Try

Dim ex As Exception = CType(e.ExceptionObject, Exception)



WriteErrorLog(ex)



Catch exc As Exception



End Try

End Sub



From method:







WriteErrorLog(ByVal ex As Exception)





You can create your own method to log the error. Note that you do not need of :







Application.SetUnhandledExceptionMode(UnhandledExceptionMode.Automatic)





At all and even less turning off the application framework.



Hope this will help someone.



dalkar69

Catch Exception in VS2010

I am under Visual Studio 2010 in a Windows Application Project with framework 4. So to achieve your need you right click on My Project Folder and click open. Under Application tab (the default one) click on the latest button View Application Events. This will create an ApplicationEvents class. Open it and copy paste this code :






Public Sub My_Startup(ByVal sender As Object, ByVal e As Microsoft.VisualBasic.ApplicationServices.StartupEventArgs) Handles Me.Startup



AddHandler AppDomain.CurrentDomain.UnhandledException, AddressOf CurrentDomain_UnhandledException

AddHandler System.Windows.Forms.Application.ThreadException, AddressOf UIThreadException



End Sub





Private Sub UIThreadException(ByVal sender As Object, ByVal ex As ThreadExceptionEventArgs)



Try



WriteErrorLog(ex.Exception)



Catch



Finally



End Try



End Sub



' Handle the UI exceptions by showing a dialog box, and asking the user whether

' or not they wish to abort execution.

' NOTE: This exception cannot be kept from terminating the application - it can only

' log the event, and inform the user about it.

Private Sub CurrentDomain_UnhandledException(ByVal sender As Object, ByVal e As System.UnhandledExceptionEventArgs)

Try

Dim ex As Exception = CType(e.ExceptionObject, Exception)



WriteErrorLog(ex)



Catch exc As Exception



End Try

End Sub



From method:







WriteErrorLog(ByVal ex As Exception)





You can create your own method to log the error. Note that you do not need of :







Application.SetUnhandledExceptionMode(UnhandledExceptionMode.Automatic)





At all and even less turning off the application framework.



Hope this will help someone.



dalkar69

Monday, April 25, 2011

How to debug a hang process

http://blogs.msdn.com/b/kirillosenkov/archive/2008/12/07/how-to-debug-crashes-and-hangs.aspx


How to debug crashes and hangs



At my job on the C# IDE QA team I've learned some useful things about debugging in Visual Studio, which I'd like to summarize in this post. Although the screenshots were made using Visual Studio 2008 SP1, this pretty much applies to other versions of VS as well.



Rich debugging support



When you develop your C# application and hit F5, the target process (your program) gets started, and then the Visual Studio process attaches the debugger to the process where your code is running. This way, you can break into the debugger and VS will provide you with all sorts of rich debugging support - current statement highlighting, call stack, watches, locals, immediate window, Edit-and-Continue and so on.



More importantly, if your application throws an exception or crashes, the debugger will intercept that and provide your with all the information about the exception.



As a side note, in Visual Studio there is a way to run your code without attaching the debugger - the shortcut is Ctrl+F5. Try throwing an exception in your code when using F5 and Ctrl+F5 to feel the difference.



throw null;



By the way, my favorite way to artificially throw exceptions is throw null; I just love the fact that it throws a NullReferenceException because it can't find the exception object and nevertheless does exactly what I want it to do :)



Crashes and the Watson dialog



What if a program crashes or throws an exception, which you don't have source code for? Moreover, you didn't start the program using F5, but the operating system launched the process. I remember that before coming to Microsoft, the only thing I could do about some application crashing was to express my disappointment about the fact (usually in Russian). Now I don't feel helpless anymore, because I've learned a couple of tricks. As an example for this we'll crash Visual Studio itself and then debug the crash.



How to crash Visual Studio?



Viacheslav Ivanov reported an interesting crashing bug in our language service recently. Save all your work and then paste this code in a C# Console Application and change 'object' to 'int':



using System;



static class Program

{

static void Main()

{

ITest

Sunday, April 24, 2011

Create new usergroup from command line

Copied from
http://www.windows-commandline.com/2009/05/add-user-to-group-from-command-line.html

On Windows computer we can add users to a group from command line too. We can use net localgroup command for this.






net localgroup group_name UserLoginName /add



For example to add a user to administrators group from command line we can run the below command. In the below example I have taken username as John.



net localgroup administrators John /add



Few more examples:



To add a domain user to local users group from command line:





net localgroup users domainname\username /add





This command should be run when the computer is connected to the network. Otherwise you will get the below error.





H:\>net localgroup users domain\user /add

System error 1789 has occurred.



The trust relationship between this workstation and the primary domain failed.

To add a domain user to local administrator group from command line:



net localgroup administrators domainname\username /add



To add a user to remote desktop users group:



net localgroup "Remote Desktop Users" UserLoginName /add



To add a user to debugger users group:



net localgroup "Debugger users" UserLoginName /add





To add a user to Power users group:



net localgroup "Power users" UserLoginName /add



This command works on all editions of Windows OS i.e Windows 2000, Windows XP, Windows Server 2003, Windows Vista and Windows 7. In Vista and Windows 7, even if you run the above command from administrator login you may still get access denied error like below.





C:\> net localgroup administrators techblogger /add

System error 5 has occurred.



Access is denied.



The solution for this is to run the command from elevated administrator account. See How to open elevated administrator command prompt



When you run the 'net localgroup' command from elevated command prompt:





C:\Windows\system32>net localgroup administrators techblogger /add

The command completed successfully.



To list the users belonging to a particular group we can run the below command.



net localgroup group_name



For example to list all the users belonging to administrators group we need to run the below command.



net localgroup administrators

Sleep command

In QMSL QPHONEMS/user defined transport, we use sleep(1) in worker thread to pull data from virtual COM ports. However, this “Sleep(1)” doesn’t really yield 1ms to other thread to execute. In fact, it yields close to 15ms. This symptom was observed in different incidents




1. Adnan’s station will take 10 mins to program LCU when “Sleep()” is used to control to data flow into the device. Other machines will take 3 mins

2. Foxconn’s machine takes 133 seconds to backup NVs with QPHONEMS. The same QMSL APIs running with QPST takes 20. This issue was later reproduced with QRD2 and QDART1.



It turns out that the default clock res, which is 15.625ms, affects the sleep behavior in OS.



You can download the tool from

http://technet.microsoft.com/en-us/sysinternals/bb897568.aspx

to check the clock res.



The slow machine has a clock resolution of 15.625ms. The normal machine has a clock resolution of 0.977ms (1/16 clock of 15.625). These slow machines usually don’t have much software installed. I guess some software, such as GPIB driver, running in background changes the default resolution to 0.977ms. In which, Sleep(1) will yield close to 1ms.



It turns out that there is undocumented API to change the clock resolution. The API is called “NtSetTimerReolution” in NTDLL.dll



http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/Time/NtSetTimerResolution.html



Once I call the API outside QMSL, all the problems were solved.



I plan to make some changes to QMSL worker thread.



1. Incorporate “NtSetTimerReoution” before worker thread is started

2. Expose new QMSL API to configure how often the worker thread goes to sleep. Currently, it sleep at each iteration. It takes 22 sec to backup NV in QPST mode. It takes 27s in QPHONEMS. Reducing the sleep frequency will speed up QHONEMS performance at the cost CPU usage. The default will still be Sleep(1) per iteration. The performance delta will be realized in 1) NON-Signaling test, 2) GPS I/Q capture, 3) NV backup/restore.

Monday, April 18, 2011

Threading

http://msdn.microsoft.com/en-us/library/system.threading.thread.start.aspx

When two or more threads need to access a shared resource at the same time, the system needs a synchronization mechanism to ensure that only one thread at a time uses the resource. Mutex is a synchronization primitive that grants exclusive access to the shared resource to only one thread. If a thread acquires a mutex, the second thread that wants to acquire that mutex is suspended until the first thread releases the mutex.
You can use the WaitHandle.WaitOne method to request ownership of a mutex. The thread that owns a mutex can request the same mutex in repeated calls to WaitOne without blocking its execution. However, the thread must call the ReleaseMutex method the same number of times to release ownership of the mutex. The Mutex class enforces thread identity, so a mutex can be released only by the thread that acquired it. By contrast, the Semaphore class does not enforce thread identity.
If a thread terminates while owning a mutex, the mutex is said to be abandoned. The state of the mutex is set to signaled, and the next waiting thread gets ownership. Beginning in version 2.0 of the .NET Framework, an AbandonedMutexException is thrown in the next thread that acquires the abandoned mutex. Before version 2.0 of the .NET Framework, no exception was thrown.

Mutexes are of two types: local mutexes, which are unnamed, and named system mutexes. A local mutex exists only within your process. It can be used by any thread in your process that has a reference to the Mutex object that represents the mutex. Each unnamed Mutex object represents a separate local mutex.
Named system mutexes are visible throughout the operating system, and can be used to synchronize the activities of processes. You can create a Mutex object that represents a named system mutex by using a constructor that accepts a name. The operating-system object can be created at the same time, or it can exist before the creation of the Mutex object. You can create multiple Mutex objects that represent the same named system mutex, and you can use the OpenExisting method to open an existing named system mutex.

Friday, April 8, 2011

ShutDown remote desktop

here are 10 ways to get the option to Shutdown or Restart a Remote Desktop:




1. Press CTRL+ALT+END to get to the Task Manager, and then click Shutdown (apparently does not always work).



2. Press CTRL+SHIFT+ESC to get to the Task Manager.



3. Right click on the TaskBar and select the Task Manager.



4. For the Classic Start Menu, left click on Start, Settings, Windows Security to get to the Task Manager.



5. For the "new" Start Menu, left click on Start, Windows Security to get to the Task Manager.



6. Create a shortcut to the Task Manager (usually located at C:/WINDOWS/system32/taskmgr.exe) and put it on the desktop or taskbar [my own solution before I found this site]



7. Click Start, Run, type "shutdown -i" (without the quotes), click OK, to get a GUI that apparently doesn't use the Task Manager (this seems to require that Directory Services be running so as to be able to browse for the computer to shut down, or you must manually add the name of the remote computer to be shut down).



8. Click Start, Run, type "shutdown -r -t xx" (without the quotes) [xx=how many xx seconds to execute this command], click OK (I've not tried this myself).



9: Click on a blank area of the desktop or taskbar, press Alt-F4, and the standard Stand By, Turn Off, Restart dialog appears.

Tuesday, April 5, 2011

Rn vbscript

cmd cscript.exe c:\test.vbs
ctrl + c to break

Sunday, April 3, 2011

How to find out in C# if it's 64 bit or 32 bit machine

public static class Wow


{

public static bool Is64BitProcess

{

get { return IntPtr.Size == 8; }

}



public static bool Is64BitOperatingSystem

{

get

{

// Clearly if this is a 64-bit process we must be on a 64-bit OS.

if (Is64BitProcess)

return true;

// Ok, so we are a 32-bit process, but is the OS 64-bit?

// If we are running under Wow64 than the OS is 64-bit.

bool isWow64;

return ModuleContainsFunction("kernel32.dll", "IsWow64Process") && IsWow64Process(GetCurrentProcess(), out isWow64) && isWow64;

}

}



static bool ModuleContainsFunction(string moduleName, string methodName)

{

IntPtr hModule = GetModuleHandle(moduleName);

if (hModule != IntPtr.Zero)

return GetProcAddress(hModule, methodName) != IntPtr.Zero;

return false;

}



[DllImport("kernel32.dll", SetLastError=true)]

[return:MarshalAs(UnmanagedType.Bool)]

extern static bool IsWow64Process(IntPtr hProcess, [MarshalAs(UnmanagedType.Bool)] out bool isWow64);

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError=true)]

extern static IntPtr GetCurrentProcess();

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]

extern static IntPtr GetModuleHandle(string moduleName);

[DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError=true)]

extern static IntPtr GetProcAddress(IntPtr hModule, string methodName);

}




With the arrival of .Net 4, we now have two new methods (click for details):
Environment.Is64BitOperatingSystem()
Environment.Is64BitProcess()

Friday, April 1, 2011

Interview questions

1)What is Multi-tasking ?


Its a feature of modern operating systems with which we can run multiple programs at same time example Word,Excel etc.



(2)What is Multi-threading ?

Multi-threading forms subset of Multi-tasking instead of having to switch between programs this feature switches between different parts of the same program.Example you are writing in word and at the same time word is doing a spell check in background.



(3)What is a Thread ?

A thread is the basic unit to which the operating system allocates processor time.



(4)Did VB6 support multi-threading ?

While VB6 supports multiple single-threaded apartments, it does not support a free-threading model, which allows multiple threads to run against the same set of data.



(5)Can we have multiple threads in one App domain ?

One or more threads run in an AppDomain. An AppDomain is a runtime representation of a logical process within a physical process.Each AppDomain is started with a single thread, but can create additional threads from any of its threads. Note :- All threading classes are defined in System.Threading namespace.



(6)Which namespace has threading ?

Systems.Threading has all the classes related to implement threading.Any .NET application who wants to implement threading has to import this namespace. Note :- .NET program always has atleast two threads running one the main program and second the garbage collector.



(7)How can we change priority and what the levels of priority are provided by .NET ?

Thread Priority can be changed by using Threadname.Priority = ThreadPriority.Highest.In the sample provided look out for code where the second thread is ran with a high priority.

Following are different levels of Priority provided by .NET :-

v ThreadPriority.Highest

v ThreadPriority.AboveNormal

v ThreadPriority.Normal

v ThreadPriority.BelowNormal

v ThreadPriority.Lowest



(8)What does Addressof operator do in background ?

The AddressOf operator creates a delegate object to the BackgroundProcess method. A delegate within VB.NET is a type-safe, object-oriented function pointer. After the thread has been instantiated, you begin the execution of the code by calling the Start() method of the thread



(9)How can you reference current thread of the method ?

"Thread.CurrentThread" refers to the current thread running in the method."CurrentThread" is a public static property.



(10) What's Thread.Sleep() in threading ?

Thread's execution can be paused by calling the Thread.Sleep method. This method takes an integer value that determines how long the thread should sleep. Example Thread.CurrentThread.Sleep(2000).



(11)How can we make a thread sleep for infinite period ?

You can also place a thread into the sleep state for an indeterminate amount of time by calling Thread.Sleep (System.Threading.Timeout.Infinite).To interrupt this sleep you can call the Thread.Interrupt method.









(12) What is Suspend and Resume in Threading ?

It is Similar to Sleep and Interrupt. Suspend allows you to block a thread until another thread calls Thread.Resume. The difference between Sleep and Suspend is that the latter does not immediately place a thread in the wait state. The thread does not suspend until the .NET runtime determines that it is in a safe place to suspend it. Sleep will immediately place a thread in a wait state. Note :- In threading interviews most people get confused with Sleep and Suspend.They look very similar.



(13)What the way to stop a long running thread ?

Thread.Abort() stops the thread execution at that moment itself.



(14)What's Thread.Join() in threading ?

There are two versions of Thread.Join :-

v Thread.join().

v Thread.join(Integer) this returns a boolean value.

The Thread.Join method is useful for determining if a thread has completed before starting another task. The Join method waits a specified amount of time for a thread to end. If the thread ends before the time-out, Join returns True; otherwise it returns False.Once you call Join the calling procedure stops and waits for the thread to signal that it is done. Example you have "Thread1" and "Thread2" and while executing 'Thread1" you call "Thread2.Join()".So "Thread1" will wait until "Thread2" has completed its execution and the again invoke "Thread1". Thread.Join(Integer) ensures that threads do not wait for a long time.If it exceeds a specific time which is provided in integer the waiting thread will start.



(15)What are Daemon thread's and how can a thread be created as Daemon?

Daemon thread's run in background and stop automatically when nothing is running program.Example of a Daemon thread is "Garbage collector".Garbage collector runs until some .NET code is running or else its idle. You can make a thread Daemon by Thread.Isbackground=true



(16) When working with shared data in threading how do you implement synchronization ?

There are a somethings you need to be careful with when using threads. If two threads (e.g. the main and any worker threads) try to access the same variable at the same time, you'll have a problem. This can be very difficult to debug because they may not always do it at exactly the same time. To avoid the problem, you can lock a variable before accessing it. However, if two threads lock the same variable at the same time, you'll have a deadlock problem. SyncLock x 'Do something with x End SyncLock



(17)Can we use events with threading ?

Yes you can use events with threads , this is one of the technique to synchronize one thread with other.



(18)How can we know a state of a thread?

"ThreadState" property can be used to get detail of a thread.Thread can have one or combination of status.System.Threading.Threadstate enumeration has all the values to detect a state of thread.Some sample states are Isrunning,IsAlive,suspended etc.











(19) What is use of Interlocked class ?

Interlocked class provides methods by which you can achieve following functionalities :-

v increment Values.

v Decrement values.

v Exchange values between variables.

v Compare values from any thread. in a synchronization mode.

Example :- System.Threading.Interlocked.Increment(IntA)



(20) what is a monitor object?

Monitor objects are used to ensure that a block of code runs without being interrupted by code running on other threads. In other words, code in other threads cannot run until code in the synchronized code block has finished. SyncLock and End SyncLock statements are provided in order to simplify access to monitor object.



(21) what are wait handles ?

Twist :- What is a mutex object ? Wait handles sends signals of a thread status from one thread to other thread.There are three kind of wait modes :-

v WaitOne.

v WaitAny.

v WaitAll.

When a thread wants to release a Wait handle it can call Set method.You can use Mutex (mutually exclusive) objects to avail for the following modes.Mutex objects are synchronization objects that can only be owned by a single thread at a time.Threads request ownership of the mutex object when they require exclusive access to a resource. Because only one thread can own a mutex object at any time, other threads must wait for ownership of a mutex object before using the resource. The WaitOne method causes a calling thread to wait for ownership of a mutex object. If a thread terminates normally while owning a mutex object, the state of the mutex object is set to signaled and the next waiting thread gets ownership



(22) what is ManualResetEvent and AutoResetEvent ?

Threads that call one of the wait methods of a synchronization event must wait until another thread signals the event by calling the Set method. There are two synchronization event classes. Threads set the status of ManualResetEvent instances to signaled using the Set method. Threads set the status of ManualResetEvent instances to nonsignaled using the Reset method or when control returns to a waiting WaitOne call. Instances of the AutoResetEvent class can also be set to signaled using Set, but they automatically return to nonsignaled as soon as a waiting thread is notified that the event became signaled.



(23) What is ReaderWriter Locks ?

You may want to lock a resource only when data is being written and permit multiple clients to simultaneously read data when data is not being updated. The ReaderWriterLock class enforces exclusive access to a resource while a thread is modifying the resource, but it allows nonexclusive access when reading the resource. ReaderWriter locks are a useful alternative to exclusive locks that cause other threads to wait, even when those threads do not need to update data.

(24) How can you avoid deadlock in threading ?

A good and careful planning can avoid deadlocks.There so many ways microsoft has provided by which you can reduce deadlocks example Monitor ,Interlocked classes , Wait handles, Event raising from one thread to other thread , ThreadState property which you can poll and act accordingly etc.

(25) What’s difference between thread and process?

A thread is a path of execution that run on CPU, a process is a collection of threads that share the same virtual memory. A process has at least one thread of execution, and a thread always run in a process context. Note:- Its difficult to cover threading interview question in this small chapter.These questions can take only to a basic level.If you are attending interviews where people are looking for threading specialist , try to get more deep in to synchronization issues as that's the important point they will stress.

Friday, March 18, 2011

C# Control.beginInvoke

C# BeginInvoke

One important difference is that when you invoked Control.BeginInvoke you are not obliged to call Control.EndInvoke. However, when you call Delegate.BeginInvoke you should also call Delegate.EndInvoke, otherwise you will have a memory leak!
You are developing this shiny new multithreaded .NET application that has this spanking new UI. You are done coding and it's time for giving a demo to your boss. And while running the demo, the UI hangs. Just hangs. Damn it, you say, it was working fine on my PC. You go back to your source and try to figure out why that happened. After a lot of poking around/debugging/swearing, you notice that you call this simple property on a control and it never returns. Or sometimes, it returns, but doesn't update the UI correctly. You then read something about calling BeginInvoke. What's that, you wonder. This article will try to answer that. Note that this article will be dealing with the BeginInvoke method on the System.Windows.Forms.Control and not the BeginInvoke method that can be called on delegates to run them asynchronously.

What does BeginInvoke do?

According to MSDN, Control.BeginInvoke "Executes the specified delegate asynchronously on the thread that the control's underlying handle was created on". It basically takes a delegate and runs it on the thread that created the control on which you called BeginInvoke. Why do I need to do that, you ask. To understand why, you have to know about how Windows processes UI actions.

Message queue and Message pumping

Every Windows application you create is provided with a thread on startup. It's this thread that calls the Main method of your application. For a console application, you can write Main to accept user input and process them. For a GUI application, things are radically different. GUI applications are event based, which means that there needs to be some entity to process and fire events. Windows manages this by creating a message queue for your application. All UI related actions get translated to messages that get posted to this message queue 1. Now, you need someone to read the messages from the queue and call appropriate event handlers. That's what a message pump is for. It basically is a loop that waits for someone to post a message to the queue. Once someone does, it dequeues it and calls the associated event handler. It can be thought of as:

Collapse
Copy Code

Message message = null;

while ((message = GetNextMessage()) != null)

{

ProcessMessage(message);

}

}

Where does the message pump run? On the Main thread, of course. So a typical GUI application, after doing some initialization in the Main method, will then start running the message pump. The while loop will exit only when the application closes, so that means the Main thread can't do anything else once the message pump starts. In .NET GUI applications, the Application.Run method takes care of message pumping. You'll see that every .NET GUI application's Main method looks like this:

Collapse
Copy Code

public static void Main(string[] args)

{

Form f = new Form();

Application.Run(f);

}

That fits in nicely with our theory, Application.Run will run the message loop on the thread on which it is called. In our case, it is the main thread and you can verify that the thread doesn't get past Application.Run until the application closes by running it under the debugger. As an aside, modal dialogs (shown using Form.ShowDialog) have their own message pump whereas modeless dialogs (shown using Form.Show) don't. Which means that you can call Form.ShowDialog from any thread but Form.Show requires the calling thread to be running a message pump. Note that if you call Form.Show from a UI event handler, both the new form and the current form will be sharing the same message pump, which means that if one form is stuck executing one of the event handlers, the other one won't be usable too.

The One Rule

One of the cardinal rules of Windows GUI programming is that only the thread that created a control can access and/or modify its contents (except for a few documented exceptions). Try doing it from any other thread and you'll get unpredictable behavior ranging from deadlock, to exceptions to a half updated UI. The right way then to update a control from another thread is to post an appropriate message to the application message queue. When the message pump gets around to executing that message, the control will get updated, on the same thread that created it (remember, the message pump runs on the main thread).

Let's go deeper into the Win32 world. There are two fundamental Win32 API calls to access and/or modify a control, SendMessage and PostMessage. There is a big difference in the way the two execute. The major difference is that SendMessage blocks the caller till the message gets processed by the message pump whereas PostMessage returns immediately. The subtle but important difference is that messages sent using SendMessage aren't queued in the message queue whereas PostMessage messages are. SendMessage messages are directly "sent" to the message pump. The message pump retrieves and processes messages sent using SendMessage before looking into those in the message queue. Effectively, there are then two queues, one for SendMessage messages and one for PostMessage messages (which is what we call the message queue). The message pump processes all messages in the first queue before starting with the second. An interesting observation is that if code does a SendMessage from within the message pumping thread, the window procedure gets called directly, that is, it doesn't go through the message pump.

Why The One Rule Exists

Now it should be fairly obvious as to why the rule is around. The first reason is the blocking nature of SendMessage. Imagine a situation where the message pumping thread is waiting for your thread to complete and your thread does a SendMessage. SendMessage will return only after the message pump has processed the message, but the message pump is stuck waiting for the thread to complete. Deadlock, and we know it's not exactly fun.

In .NET, property/method calls on a Control object translate to SendMessage calls, so you can easily see how it can turn nasty. PostMessage posts a message to the queue and returns immediately, so there is no chance of deadlock.

The second reason is more subtle. Because there are effectively two queues, it's quite possible that at one point in time, both queues have the same message but with different parameters. Let's assume the message sets the text of a control and that you've used SendMessage. The message pump first processes SendMessage messages and the text is set to a particular value. It next starts processing messages in the message queue (sent using PostMessage). Along comes the same message from the message queue and it overwrites the previous value with its parameters. You never know when the message from the message queue was posted, it's very much possible that it was posted before you issued SendMessage. In that case, your most recent update gets overwritten with an older one. If the SendMessage message was to read the text of the control, it'll return a wrong value because the PostMessage message that executes later will set it to something else and that's what will be visible in the UI.

If instead of SendMessage, you had used PostMessage, then both messages would have gone to the same queue and barring race conditions as to who posted first to the queue, the order would have been preserved.

There is one other issue with using SendMessage that is not obvious at all. SendMessage, while blocking the current thread, continues to process messages that are sent to the message pump using SendMessage or one of the functions that send nonqueued[^] messages. This means that your code must be prepared to handle incoming messages when blocked on a SendMessage call. This can cause problems if your code depends on SendMessage to be a truly blocking function and doesn't use any other synchronization mechanism. For e.g., consider this piece of code:

Collapse
Copy Code

void ButtonClick_Handler(object sender, EventArgs e)

{

int val = count; // count is a class member variable

SendMessage(...);

Console.WriteLine(val == count); // Surprise, val != count can happen!

}



void SomeOtherMessageHandler()

{

count++;

}

When the above piece of code is blocking on the SendMessage and someone else does a SendMessage to this application that causes SomeOtherMessageHandler to execute, then val will not be equal to count. The core of the issue is that SomeOtherMessageHandler will execute even if ButtonClick_Handler is blocked on SendMessage, which is not what most people expect. To avoid such problems, Windows provides the SendMessageTimeout API function, which when called with the right parameters, will prevent pumping of nonqueued messages when blocked on sending a message. However, all .NET UI controls use SendMessage, so you can't avoid the problem, unless you are planning on doing P/Invoke.

If you're still not convinced that SendMessage from a different thread is not a great idea, see this post for a great practical example.

Why and when to call BeginInvoke

With all that stuff inside our head now, we can easily figure out the reason for the existence of BeginInvoke. It essentially does a PostMessage. Whenever you want to update a control from a thread that didn't create it, instead of directly calling the method/property to update it, you need to wrap it in a BeginInvoke call. According to MSDN: "There are four methods on a control that are safe to call from any thread: Invoke, BeginInvoke, EndInvoke, and CreateGraphics. For all other method calls, you should use one of the invoke methods to marshal the call to the control's thread". One of the invoke methods, you say, what are the others? Well, the Control class provides one property and two methods to do the stuff we discussed.

InvokeRequired: This bool property returns true if the thread on which this property is called is not the thread that created this control. Basically, if InvokeRequired returns true, you need to call one of the two Invoke methods.

BeginInvoke: This is a functionally similar to the PostMessage API function. It posts a message to the queue and returns immediately without waiting for the message to be processed. BeginInvoke returns an IAsyncResult, just like the BeginInvoke method on any delegate. And you can use IAsyncResult to wait for the message to be processed, just as usual. And you can call EndInvoke to get return values or out parameter values, as usual.

Invoke: This is like the SendMessage API function in that it waits till the message gets processed, but it does not do a SendMessage internally, it also does a PostMessage. The difference is that it waits till the delegate is executed on the UI thread before returning. So while there is a chance for the deadlock problem to occur, you can be sure that the other problems associated with SendMessage won't happen. Invoke returns the value that the function wrapped by the delegate returned.

A typical piece of code using BeginInvoke will look like this:

Collapse
Copy Code

public class FormFoo : Form

{

Label label = new Label();

public static void Main()

{

Application.Run(new FormFoo());

}



public FormFoo()

{

InitializeComponent();



Thread t = new Thread(new ThreadStart(ChangeLabel));

t.Start();

}



private void ChangeLabel()

{

for (int i = 0; i<100; ++i)

{

SetLabelText(i);

Thread.Sleep(1000);

}

}

private delegate void SetLabelTextDelegate(int number);

private void SetLabelText(int number)

{

// label.Text = number.ToString();

// Do NOT do this, as we are on a different thread.



// Check if we need to call BeginInvoke.

if (this.InvokeRequired)

{

// Pass the same function to BeginInvoke,

// but the call would come on the correct

// thread and InvokeRequired will be false.

this.BeginInvoke(new SetLabelTextDelegate(SetLabelText),

new object[] {number});



return;

}



label.Text = number.ToString();

}

}

Assigning a value to label.Text directly in SetLabelText will result in a SendMessage to the underlying control from the current thread and we saw in excruciating detail why it is troublesome. So we use BeginInvoke, passing the same function as the delegate parameter, which will post a message to the handle of this. When the message pump dispatches the message, it'll call SetLabelText and in that invocation, InvokeRequired will return false. We then set the Label's text, confident that we are on the right thread.

The BCL provides a MethodInvoker delegate, which you can use if your wrapped function takes no parameters and returns void. You can also reuse the EventHandler delegate in case your wrapped function's signature matches it. The MSDN documentation says using these delegates instead of our own custom delegates will result in faster execution.

Both BeginInvoke and Invoke check if they are called on the correct thread (the thread that created the control) and if so, directly update the control instead of doing the PostMessage thing. Apart from performance benefits, it also prevents deadlock if you call Invoke from within a method already running on the UI thread.

Invoke and BeginInvoke

Which function to use, you ask. It really depends on your requirement. If you want your UI update to complete before proceeding, you use Invoke. If there is no such requirement, I'd suggest using BeginInvoke, as it makes the thread calling it seemingly "faster". There are a few gotcha's with BeginInvoke though.

If the function you are calling via BeginInvoke accesses shared state (state shared between the UI thread and other threads), you are in trouble. The state might change between the time you called BeginInvoke and when the wrapped function actually executes, leading to hard to find timing problems.

If you are passing reference parameters to the function called via BeginInvoke, then you must make sure that no one else modifies the passed object before the function completes. Usually, people clone the object before passing it to BeginInvoke, which avoids the problem altogether.

Note that the above points are valid for any function that you run as a thread. They're not so obvious when using BeginInvoke, because BeginInvoke doesn't actually create a thread and instead runs the wrapped function on an already existing thread (the UI thread). It still means that there are two threads, so you want to take the same care protecting your shared variables.

If your code is based on .NET 1.1 (including SP1), there is a bug in the framework implementation of Invoke which could cause it to hang indefinitely on multiprocessor machines. The bug has been fixed in .NET 2.0 and as this KB article says, there is a hotfix available for 1.1, but it can only be obtained by calling PSS. You could always call BeginInvoke and use a custom signalling mechanism instead. Here is the description of the actual problem, in case you're interested.

A warning

Control.BeginInvoke, which is what we have been discussing so far, works slightly differently from Delegate.BeginInvoke. Delegate.BeginInvoke grabs a threadpool thread and executes the passed delegate on that thread. Control.BeginInvoke does not use a threadpool thread, it does a PostMessage to the target window handle and returns. This is crucial because if it uses threads, then there is no guarantee to the order in which messages are posted and processed by the application. Also, unlike Delegate.BeginInvoke, Control.BeginInvoke doesn't require every call to BeginInvoke to be matched by an EndInvoke. Of course, if you are using the return value of the method and/or out or ref values, then you need to call it anyway.

Conclusion

Judging from the number of posts in the C# forum resulting from the improper use of BeginInvoke, this seems to be a poorly understood topic. Hopefully this article will help clarify things a bit. In .NET 2.0, the CLR straightaway throws an exception if you attempt to do a cross thread UI update. In fact, I'd suggest compiling your app for the 2.0 platform and running the app through all possible scenarios, just to make sure there are no inadvertent cross thread UI updates.

Appendix

Note 1 Not entirely true, as explained later in the article. Some of the messages are posted to the message queue (PostMessage) and some are directly sent to the message pump (SendMessage). Sent messages are processed first before processing messages in the message queue.

History

Initial post on 07-May-2005.

Added explanation for The One Rule. Corrected major error in description of SendMessage [11-May-2005].

Beefed up the "Why the One Rule exists" section and made miscellaneous modifications [5-June-2005].

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

STAThread

STAThread


When the STAThreadAttribute is applied, it changes the apartment state of the current thread to be single threaded. Without getting into a huge discussion about COM and threading, this attribute ensures the communication mechanism between the current thread and other threads that may want to talk to it via COM. When you're using Windows Forms, depending on the feature you're using, it may be using COM interop in order to communicate with operating system components. Good examples of this are the Clipboard and the File Dialogs.

Windows Forms is not supported within a MTA or free threaded apartment. Applications using Windows Forms should always declare the apartment style they're using, as some other component could initialize the apartment state of thread improperly.

If the application cannot control the apartment state of the current thread, it should start up a new thread. Here's a quick example:

using System.Threading;



Thread t = new Thread(new ThreadStart(StartNewStaThread));



// Make sure to set the apartment state BEFORE starting the thread.

t.ApartmentState = ApartmentState.STA;

t.Start();



private void StartNewStaThread() {

Application.Run(new Form1());

}

Thursday, March 17, 2011

Observer method to replace events and delegates

to create an observer interface with detach/attach/notify method

Friday, March 11, 2011

How to create interop type library using tlbimp

c:\Program Files\Microsoft Visual Studio 9.0\VC>tlbimp C:\HIVECOMKERNEL\ReleaseB

in\HIVECOMKernel.dll /namespace:HIVECOMKERNELLib /out:C:\HIVECOMKERNEL\ReleaseBi

n\Interop.HIVECOMKERNELLib.dll

Monday, January 24, 2011

Capture error from Computer systems & debug a crashed process

In VS, uncheck Enable Just My Code option under Options->debugging->general, when a process crashed, go to Attach to Process->and choose the process, click on Break All breakpoints and should be able to view the stack trace and the line of code that caused the crashed.

Your operating system's system log may also have a crash report. The information will probably include the name of the module that caused the crash. On recent Windows versions, go to Start > Settings > Control Panel > Administrative Tools > Event Viewer. In the application tab, right-click on the event and select Properties. When you report the event, you should copy the information from the log.

Tuesday, January 18, 2011

Redirect console to a file

string sourceDirectory = @"C:\Log";


if (!Directory.Exists(sourceDirectory))

Directory.CreateDirectory(sourceDirectory);



//write to a log file also all the output messages for debugging later

using (FileStream fs = new FileStream(Path.Combine(sourceDirectory, "CreateGroups.log"), FileMode.Create))

{

using (StreamWriter sw = new StreamWriter(fs))

{

Console.SetOut(sw);

Console.WriteLine(string.Format("{0} - ", DateTime.Now) + "Starting to add group " + groupName);
Console.WriteLine(string.Format("{0} - ", DateTime.Now) + "Found the NT directory.");
sw.Close();

}

}

Monday, January 17, 2011

DirectoryServices, create groups, add users to group

using System;


using System.Collections.Generic;

using System.Text;

using System.DirectoryServices;

using System.Diagnostics;

using System.IO;



namespace CreateQSPRUserGroups

{

class Program

{

private string QTM_Directory = @"C:\Program Files\QUALCOMM\QDART\bin";

private const string SUBKEY = "Path";



private const string QSPR_POWER_USERS = "QSPR Power Users";

private const string QSPR_GROUP_DESCRIPTION = "QSPR Power Users have Engineer Privileges to run QSPR";



private const string QSPR_TECH_USERS = "QSPR Tech Users";

private const string QSPR_TECH_GROUP_DESCRIPTION = "QSPR Tech Users have Technician Privileges to run QSPR";



static void Main(string[] args)

{

//write to a log file also all the output messages for debugging later

using (FileStream fs = new FileStream("CreateGroups.log", FileMode.Create))

{

using (StreamWriter sw = new StreamWriter(fs))

{

Console.SetOut(sw);



CreateUserGroup(QSPR_POWER_USERS, QSPR_GROUP_DESCRIPTION);

CreateUserGroup(QSPR_TECH_USERS, QSPR_TECH_GROUP_DESCRIPTION);

AddAdminUsersToGroup();

sw.Close();

}

}



}



private static void CreateUserGroup(string groupName, string groupDescription)

{

try

{

Console.WriteLine(string.Format("{0} - ", DateTime.Now) + "Starting to add group " + groupName);

DirectoryEntry entry = new DirectoryEntry("WinNT://" +

Environment.MachineName + ",computer");

Console.WriteLine(string.Format("{0} - ", DateTime.Now) + "Found the NT directory.");



DirectoryEntry qtmGroup = entry.Children.Add(groupName, "group");

Console.WriteLine(string.Format("{0} - ", DateTime.Now) + "Setup the group");

qtmGroup.Invoke("Put", new object[] { "Description", groupDescription });

Console.WriteLine(string.Format("{0} - ", DateTime.Now) + "Setup the group's description");



qtmGroup.CommitChanges();

Console.WriteLine(string.Format("{0} - ", DateTime.Now) + groupName + " added");



}

catch (Exception ex)

{

Console.WriteLine(string.Format("{0} - ", DateTime.Now) + string.Format("Failed to create user group {0}, Error: {1}, InnerException: {2}",

groupName, ex.Message, ex.InnerException));

}

}



private static void AddAdminUsersToGroup()

{

try

{

DirectoryEntry AD3 = new DirectoryEntry("WinNT://" +

Environment.MachineName + ",computer");



DirectoryEntry grp;

Console.WriteLine(string.Format("{0} - ", DateTime.Now) + "Finding the QSPR Power users");

grp = AD3.Children.Find(QSPR_POWER_USERS, "group");

if (grp != null)

{

using (DirectoryEntry groupEntry = new DirectoryEntry("WinNT://./Administrators,group"))

{

foreach (object member in (System.Collections.IEnumerable)groupEntry.Invoke("Members"))

{

using (DirectoryEntry memberEntry = new DirectoryEntry(member))

{

try

{

grp.Invoke("Add", new object[] { memberEntry.Path.ToString() });

Console.WriteLine(string.Format("{0} - ", DateTime.Now) + "Adding user " + memberEntry.ToString());

}

catch (Exception ex)

{

Console.WriteLine(string.Format("{0} - ", DateTime.Now) + "User already added." + ex.Message);

}



}

}

}

}



}

catch (Exception ex)

{

Console.WriteLine(string.Format("{0} - ", DateTime.Now) + string.Format("Add admin users failed, Error: {0}, InnerException: {1}", ex.Message, ex.InnerException));

}

}

}

}

Monday, January 10, 2011

Serialize and deserialize an xml file and convert to xsd

http://msdn.microsoft.com/en-us/library/2baksw0z.aspx  on Controlling XML Serialization Using Attributes


- Convert an xml file to xsd by using the VS command promt xsd.exe /c filename.xml to get xsd
- convert from an xsd to .net class xsd.exe /c filename.xsd to get .cs file


can use XmlWriterSettings settings = new XmlWriterSettings();


settings.Indent = true;

settings.OmitXmlDeclaration = true;

settings.NewLineOnAttributes = true;



writer = XmlWriter.Create(Console.Out, settings);




public void SaveParamViewLayout()


{

TextWriter writer = null;

try

{

string fileNameGridLayout = Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), Path.Combine(QTM.FeatureConfigInfo.ConfigDirectory, ConfigFileNameConst.TTD_PARAM_VIEW_LAYOUT_FNAME));

ParamViewLayout currLayout = new ParamViewLayout(ultraGridInput.Size, ultraGridOutput.Size);

writer = new StreamWriter(fileNameGridLayout);

System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(typeof(ParamViewLayout));



//serialize it to the file

x.Serialize(writer, currLayout);

writer.Close();

}

catch

{ }

finally

{

if (writer != null)

writer.Close();

}

}



private void RestoreParamViewLayout()

{

FileStream fs = null;

try

{

string fileNameGridLayout = Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), Path.Combine(QTM.FeatureConfigInfo.ConfigDirectory, ConfigFileNameConst.TTD_PARAM_VIEW_LAYOUT_FNAME));

if (File.Exists(fileNameGridLayout))

{

ParamViewLayout layout;

System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(typeof(ParamViewLayout));

fs = new FileStream(fileNameGridLayout, FileMode.Open);



layout = (ParamViewLayout)x.Deserialize(fs);

fs.Close();

ultraGridInput.Dock = DockStyle.None;

ultraGridOutput.Dock = DockStyle.None;

ultraGridInput.Size = layout.inputParamSize;

ultraGridOutput.Size = layout.outputParamSize;

ultraGridInput.Dock = DockStyle.Fill;

ultraGridOutput.Dock = DockStyle.Bottom;



}

}

catch //(Exception)

{

//ignore this exception

}

finally

{

if (fs != null)

fs.Close();

}

}