<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>.Net and C#</title><link>http://blogs.x2line.com/al/category/24.aspx</link><description>Posts specifically related to Microsoft .NET Framework and C#. Including runtime features and future versions of Framework, tools, configuration considerations and best practices. Also: c# specifications, design guidelines and best practices. Discussions regarding performance considerations, announcements, etc</description><managingEditor>Anatoly Lubarsky</managingEditor><dc:language>en-US</dc:language><generator>Version 0.97.2006.1</generator><image><url>http://blogs.x2line.com/Images/x2line_logo_feed.jpg</url><title>x2line: Social Network Services, Weblog Hosting</title><link>http://blogs.x2line.com/</link></image><item><dc:creator>Anatoly Lubarsky</dc:creator><title>.NET: How to Make HTTP Request and Get Response</title><link>http://blogs.x2line.com/al/archive/2008/08/29/3544.aspx</link><pubDate>Fri, 29 Aug 2008 00:34:00 GMT</pubDate><guid>http://blogs.x2line.com/al/archive/2008/08/29/3544.aspx</guid><wfw:comment>http://blogs.x2line.com/al/comments/3544.aspx</wfw:comment><comments>http://blogs.x2line.com/al/archive/2008/08/29/3544.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.x2line.com/al/comments/commentRss/3544.aspx</wfw:commentRss><trackback:ping>http://blogs.x2line.com/al/services/trackbacks/3544.aspx</trackback:ping><description>&lt;p&gt;There are so many ways to query external url in .NET, people can use so many approaches and .NET Framework classes available - it's crazy. Quering external urls via HTTP today is a common task many developers facing.&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;There are many REST (or other types of) open APIs created by external services.&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;Below I decided to post an example of how to do it the right way (as far as I can see it). This schematic function supports both POST and GET requests, highly scalable and the most important - it is designed as low level infrastructure function (i.e. uses simple types and bubbles exceptions).&lt;/p&gt;&lt;br /&gt;
&lt;pre&gt;
public string GetHttpResponse(string requestUrl, byte[] data)
{
    // declare objects
    string responseData = String.Empty;
    HttpWebRequest req = null;
    HttpWebResponse resp = null;
    StreamReader strmReader = null;

    try
    {
        req = (HttpWebRequest)HttpWebRequest.Create(requestUrl);
        

        // set HttpWebRequest properties here (Method, ContentType, etc)
        // some code

        // in case of POST you need to post data
        if ((data != null) &amp;&amp; (data.Length &gt; 0))
        {
            using (Stream strm = req.GetRequestStream())
            {
                strm.Write(data, 0, data.Length);
            }
        }

        resp = (HttpWebResponse)req.GetResponse();
        strmReader = new StreamReader(resp.GetResponseStream());
        responseData = strmReader.ReadToEnd().Trim();
    }
    catch (Exception ex)
    {
        throw;
    }
    finally
    {
        if (req != null)
        {
            req = null;
        }

        if (resp != null)
        {
            resp.Close();
            resp = null;
        }
    }

    return responseData;
}
&lt;/pre&gt;&lt;br /&gt;
&lt;p&gt;P.S. - HttpWebRequest proved to be the most reliable for me.&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;Enjoy&lt;/p&gt;&lt;img src ="http://blogs.x2line.com/al/aggbug/3544.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>Anatoly Lubarsky</dc:creator><title>How to: Get Total Physical Memory</title><link>http://blogs.x2line.com/al/archive/2008/06/14/3459.aspx</link><pubDate>Sat, 14 Jun 2008 05:59:00 GMT</pubDate><guid>http://blogs.x2line.com/al/archive/2008/06/14/3459.aspx</guid><wfw:comment>http://blogs.x2line.com/al/comments/3459.aspx</wfw:comment><comments>http://blogs.x2line.com/al/archive/2008/06/14/3459.aspx#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://blogs.x2line.com/al/comments/commentRss/3459.aspx</wfw:commentRss><trackback:ping>http://blogs.x2line.com/al/services/trackbacks/3459.aspx</trackback:ping><description>&lt;p&gt;Q: My app needs to know how much RAM the machine it's running on has. How can this information be aquired ?&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;Is there any _managed_ way of getting total physical memory installed in the machine ?&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;You can retrieve the amount of physical memory on the computer by using WMI (You could use a WMI query, the property is "TotalPhysicalMemory" which is in the "Win32_ComputerSystem" class.). However: WMI would  almost always be the slowest way to retrieve system values using C#.&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;Therefore I advice to use Win32 API - &lt;b&gt;GlobalMemoryStatus&lt;/b&gt; function included in &lt;i&gt;kernel32.dll&lt;/i&gt;:&lt;/p&gt;&lt;br /&gt;
&lt;pre&gt;
public struct MemoryStatus 
{ 
    public uint Length;  
    public uint MemoryLoad; 
    public uint TotalPhysical; 
    public uint AvailablePhysical; 
    public uint TotalPageFile; 
    public uint AvailablePageFile; 
    public uint TotalVirtual; 
    public uint AvailableVirtual; 
} 

[DllImport("kernel32.dll")] 
public static extern void GlobalMemoryStatus(out MemoryStatus stat);
&lt;/pre&gt;&lt;br /&gt;
&lt;p&gt;From managed code we can use it  like so:&lt;/p&gt;&lt;br /&gt;
&lt;pre&gt;
MemoryStatus stat = new MemoryStatus();
GlobalMemoryStatus(out stat);
long ram = (long)stat.TotalPhysical;
&lt;/pre&gt;&lt;br /&gt;
&lt;p&gt;Hope this helps.&lt;/p&gt;&lt;img src ="http://blogs.x2line.com/al/aggbug/3459.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>Anatoly Lubarsky</dc:creator><title>Reducing Memory Footprint of any Process with EmptyWorkingSet</title><link>http://blogs.x2line.com/al/archive/2008/04/20/3394.aspx</link><pubDate>Sun, 20 Apr 2008 21:07:00 GMT</pubDate><guid>http://blogs.x2line.com/al/archive/2008/04/20/3394.aspx</guid><wfw:comment>http://blogs.x2line.com/al/comments/3394.aspx</wfw:comment><comments>http://blogs.x2line.com/al/archive/2008/04/20/3394.aspx#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://blogs.x2line.com/al/comments/commentRss/3394.aspx</wfw:commentRss><trackback:ping>http://blogs.x2line.com/al/services/trackbacks/3394.aspx</trackback:ping><description>&lt;p&gt;Ever wondered why does .NET winform application takes so much memory on startup ? It is obvious that most of this memory is not in use. The reason is that JIT compiler and the whole winforms engine is loaded into the process. However it is possible to remove as many pages as possible from the working set of the specified process using &lt;i&gt;EmptyWorkingSet&lt;/i&gt; from &lt;b&gt;psapi.dll&lt;/b&gt;.&lt;/p&gt;&lt;br /&gt;
&lt;pre&gt;
[DllImport("psapi.dll")]
static extern int EmptyWorkingSet(IntPtr hwProc);
&lt;/pre&gt;&lt;br /&gt;
&lt;p&gt;From managed code we can use it  like so (for the current process):&lt;/p&gt;&lt;br /&gt;
&lt;pre&gt;
static void ClearMemory()
{
    EmptyWorkingSet(Process.GetCurrentProcess().Handle);
}
&lt;/pre&gt;&lt;br /&gt;
&lt;p&gt;However it is possible to use this function for any process which handle must have the PROCESS_QUERY_INFORMATION and PROCESS_SET_INFORMATION access rights. Be careful using EmptyWorkingSet since the process will allocate the memory again in the future when needed.&lt;/p&gt;&lt;img src ="http://blogs.x2line.com/al/aggbug/3394.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>Anatoly Lubarsky</dc:creator><title>C# Win32 API: Flash Window (FlashWindowEx)</title><link>http://blogs.x2line.com/al/archive/2008/04/19/3392.aspx</link><pubDate>Sat, 19 Apr 2008 21:11:00 GMT</pubDate><guid>http://blogs.x2line.com/al/archive/2008/04/19/3392.aspx</guid><wfw:comment>http://blogs.x2line.com/al/comments/3392.aspx</wfw:comment><comments>http://blogs.x2line.com/al/archive/2008/04/19/3392.aspx#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://blogs.x2line.com/al/comments/commentRss/3392.aspx</wfw:commentRss><trackback:ping>http://blogs.x2line.com/al/services/trackbacks/3392.aspx</trackback:ping><description>&lt;p&gt;Ever tried to flash a window using managed code ? The following method will flash the window title bar or the window taskbar button. Since there is no managed API available for this functionality - need to wrap a method imported from user32: &lt;i&gt;FlashWindowEx&lt;/i&gt;:&lt;/p&gt;&lt;br /&gt;
&lt;pre&gt;
[DllImport("user32.dll")]
static extern Int32 FlashWindowEx(ref FLASHWINFO pwfi);
&lt;/pre&gt;&lt;br /&gt;
&lt;p&gt;Where FLASHWINFO struct is defined like so:&lt;/p&gt;&lt;br /&gt;
&lt;pre&gt;
[StructLayout(LayoutKind.Sequential)]
public struct FLASHWINFO
{
    public UInt32 cbSize;
    public IntPtr hwnd;
    public Int32 dwFlags;
    public UInt32 uCount;
    public Int32 dwTimeout;
}
&lt;/pre&gt;&lt;br /&gt;
&lt;p&gt;Where &lt;i&gt;dwFlags&lt;/i&gt; can be one of the following:&lt;/p&gt;&lt;br /&gt;
&lt;pre&gt;
// stop flashing
FLASHW_STOP = 0; 

// flash the window title 
FLASHW_CAPTION = 1; 

// flash the taskbar button
FLASHW_TRAY = 2; 

// 1 | 2
FLASHW_ALL = 3; 

// flash continuously 
FLASHW_TIMER = 4; 

// flash until the window comes to the foreground 
FLASHW_TIMERNOFG = 12; 
&lt;/pre&gt;&lt;br /&gt;
&lt;p&gt;So the typical C# call will look like so:&lt;/p&gt;&lt;br /&gt;
&lt;pre&gt;
public static bool Flash()
{
    FLASHWINFO fw = new FLASHWINFO();

    fw.cbSize = Convert.ToUInt32(Marshal.SizeOf(typeof(FLASHWINFO)));
    fw.hwnd = this.Handle;
    fw.dwFlags = 2;
    fw.uCount = UInt32.MaxValue;

    FlashWindowEx(ref fw);
}
&lt;/pre&gt;&lt;br /&gt;
&lt;p&gt;See some other &lt;a href="http://blogs.x2line.com/al/category/95.aspx"&gt;C# Win32 API tips and tricks&lt;/a&gt;. Enjoy :)&lt;/p&gt;&lt;img src ="http://blogs.x2line.com/al/aggbug/3392.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>Anatoly Lubarsky</dc:creator><title>Calculate Euler Number with Recursion</title><link>http://blogs.x2line.com/al/archive/2008/03/11/3377.aspx</link><pubDate>Tue, 11 Mar 2008 04:01:00 GMT</pubDate><guid>http://blogs.x2line.com/al/archive/2008/03/11/3377.aspx</guid><wfw:comment>http://blogs.x2line.com/al/comments/3377.aspx</wfw:comment><comments>http://blogs.x2line.com/al/archive/2008/03/11/3377.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.x2line.com/al/comments/commentRss/3377.aspx</wfw:commentRss><trackback:ping>http://blogs.x2line.com/al/services/trackbacks/3377.aspx</trackback:ping><description>&lt;p&gt;I recently went through several posts I had made on one of the development forums back then in 2005. I've found one of them interesting and wanted to repost it here. The question went like this:&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;&lt;i&gt;"How can I calculate euler number with recursion ?"&lt;/i&gt;&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/E_%28mathematical_constant%29" target="_blank"&gt;Euler number&lt;/a&gt; (or &lt;b&gt;e&lt;/b&gt;) can be calculated with the following formula in math:&lt;/p&gt;&lt;br /&gt;
&lt;pre&gt;sum = 1/0! + 1/1! + 1/2! + ... + 1/n!&lt;/pre&gt;&lt;br /&gt;
&lt;p&gt;Here one can notice the use of the Factorial function which can be implemented via recursion itself  like so:&lt;/p&gt;&lt;br /&gt;
&lt;pre&gt;
int Factorial(int n) 
{
    if (n == 0) 
    {
        return 1;
    }

    return n * Factorial(n - 1);
}
&lt;/pre&gt;&lt;br /&gt;
&lt;p&gt;After we know how to implement Factorial we can implement &lt;b&gt;Euler number&lt;/b&gt; using recursion as well:&lt;/p&gt;&lt;br /&gt;
&lt;pre&gt;
double EulerNumber(int n) 
{
    if (n == 0) 
    {
        return 1;
    }

    return 1.0/Factorial(n) + EulerNumber(n - 1);
}
&lt;/pre&gt;&lt;br /&gt;
&lt;p&gt;Enjoy :)&lt;/p&gt;&lt;img src ="http://blogs.x2line.com/al/aggbug/3377.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>Anatoly Lubarsky</dc:creator><title>HOW TO: Remove Last Character from String </title><link>http://blogs.x2line.com/al/archive/2008/03/10/3369.aspx</link><pubDate>Mon, 10 Mar 2008 03:36:00 GMT</pubDate><guid>http://blogs.x2line.com/al/archive/2008/03/10/3369.aspx</guid><wfw:comment>http://blogs.x2line.com/al/comments/3369.aspx</wfw:comment><comments>http://blogs.x2line.com/al/archive/2008/03/10/3369.aspx#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://blogs.x2line.com/al/comments/commentRss/3369.aspx</wfw:commentRss><trackback:ping>http://blogs.x2line.com/al/services/trackbacks/3369.aspx</trackback:ping><description>&lt;p&gt;Very often during development we need to remove the last character from a string.&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;It could be a trailing slash or a trailing comma as a result (side effect ?) of building delimited strings.&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;There are many ways to do that in C#, however I like the following one for its simplicity and good performance:&lt;/p&gt;&lt;br /&gt;
&lt;pre&gt;
str.Remove(str.Length - 1, 1);
&lt;/pre&gt;&lt;br /&gt;
&lt;p&gt;Enjoy&lt;/p&gt;&lt;img src ="http://blogs.x2line.com/al/aggbug/3369.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>Anatoly Lubarsky</dc:creator><title>HOW TO: Read From a Locked Text File</title><link>http://blogs.x2line.com/al/archive/2008/01/26/3342.aspx</link><pubDate>Sat, 26 Jan 2008 23:12:00 GMT</pubDate><guid>http://blogs.x2line.com/al/archive/2008/01/26/3342.aspx</guid><wfw:comment>http://blogs.x2line.com/al/comments/3342.aspx</wfw:comment><comments>http://blogs.x2line.com/al/archive/2008/01/26/3342.aspx#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://blogs.x2line.com/al/comments/commentRss/3342.aspx</wfw:commentRss><trackback:ping>http://blogs.x2line.com/al/services/trackbacks/3342.aspx</trackback:ping><description>&lt;p&gt;Q: I'm trying to read a txt file using StreamReader, but the file is locked by another process. The problem is that, since this is a log file I can't stop the other process that is using it.&lt;/p&gt;&lt;br&gt;
&lt;p&gt;Even if one makes sure to specify the proper FileAccess and FileShare modes when opening the file she won't be able to read it if the other program has opened the file with an exclusive lock.&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;Since this is a very common problem I wanted to share a small but useful tip of how to do that:&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;Before you open the file simply copy it to ---&amp;gt; C:\Documents and Settings\&amp;lt;username&amp;gt;\Local Settings\Temp\. REASON: Avoids file access violations under Windows. Now open and read the copied file.&lt;/p&gt;&lt;img src ="http://blogs.x2line.com/al/aggbug/3342.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>Anatoly Lubarsky</dc:creator><title>Solution for MSI Error 2869 on Windows Vista</title><link>http://blogs.x2line.com/al/archive/2007/07/20/3210.aspx</link><pubDate>Fri, 20 Jul 2007 17:23:00 GMT</pubDate><guid>http://blogs.x2line.com/al/archive/2007/07/20/3210.aspx</guid><wfw:comment>http://blogs.x2line.com/al/comments/3210.aspx</wfw:comment><comments>http://blogs.x2line.com/al/archive/2007/07/20/3210.aspx#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://blogs.x2line.com/al/comments/commentRss/3210.aspx</wfw:commentRss><trackback:ping>http://blogs.x2line.com/al/services/trackbacks/3210.aspx</trackback:ping><description>&lt;h4&gt;What is MSI error 2869&lt;/h4&gt;
&lt;p&gt;It turns out that &lt;i&gt;Error 2869&lt;/i&gt; is the common issue with MSI installations on Windows Vista.&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;&lt;i&gt;"The installer has encountered an unexpected error installing this package. This may indicate a problem with this package. The error code is 2869"&lt;/i&gt;&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;Even MSI installations provided by Microsoft have to deal with this error which is trying to tell that the user does not have administrative privileges to install. However she does have administrative privileges (lol).&lt;/p&gt;&lt;br /&gt;
&lt;h4&gt;What is User Access Control&lt;/h4&gt;
&lt;p&gt;This happens because of UAC (&lt;i&gt;user access control&lt;/i&gt;) feature of Windows Vista. What is user access control ? To make the long story short - if you are defined as administrator on Vista - you are not.. (lol). You are only temporary granted administrator privileges when running programs.&lt;/p&gt;&lt;br&gt;
&lt;p&gt;Therefore &lt;b&gt;MSI Custom Actions&lt;/b&gt; that interact with the system and require administrative privileges will fail to run because &lt;b&gt;MSI Custom Actions&lt;/b&gt; will impersonate by default.&lt;/p&gt;&lt;br&gt;
&lt;p&gt;BTW, quick workaround will be running:&lt;/p&gt;&lt;br /&gt;
&lt;pre&gt;msiexec /i MySetup.msi&lt;/pre&gt;&lt;br /&gt;
&lt;p&gt;from a command line prompt as administrator.&lt;/p&gt;&lt;br /&gt;
&lt;h4&gt;Solution&lt;/h4&gt;
&lt;p&gt;It is possible to mark Custom Actions as &lt;b&gt;msidbCustomActionTypeNoImpersonate&lt;/b&gt; in MSI. So one can edit MSI with ORCA and patch Custom Actions table updating Type column to be &lt;b&gt;msidbCustomActionTypeNoImpersonate&lt;/b&gt; according to the &lt;a href="http://msdn2.microsoft.com/en-us/library/Aa368069.aspx" target="_blank"&gt;Custom Action In-Script Execution Options&lt;/a&gt; table. Usually it will be enough to add 1024 to the Type column in the Custom Actions for Custom Actions of install, uninstall, rollback and commit (anyway - those that require administrative privileges).&lt;/p&gt;&lt;br /&gt;
&lt;h4&gt;Visual Studio 2005&lt;/h4&gt;
&lt;p&gt;Bonus for Visual Studio 2005 developers. I advice to use &lt;b&gt;WiRunSQL.vbs&lt;/b&gt; to patch MSI automatically (Google for it :)). Go to the properties of your setup project and define post-build event that utilizes WiRunSQL.vbs. Like so:&lt;/p&gt;&lt;br /&gt;
&lt;pre&gt;@echo off
cscript /nologo "WiRunSQL.vbs" "MySetup.msi" 
"UPDATE CustomAction SET Type = 3585 WHERE Type = 1537"
&lt;/pre&gt;&lt;br /&gt;
&lt;p&gt;Enjoy&lt;/p&gt;&lt;img src ="http://blogs.x2line.com/al/aggbug/3210.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>Anatoly Lubarsky</dc:creator><title>How to Detect Process Exit</title><link>http://blogs.x2line.com/al/archive/2007/07/06/3193.aspx</link><pubDate>Fri, 06 Jul 2007 23:55:00 GMT</pubDate><guid>http://blogs.x2line.com/al/archive/2007/07/06/3193.aspx</guid><wfw:comment>http://blogs.x2line.com/al/comments/3193.aspx</wfw:comment><comments>http://blogs.x2line.com/al/archive/2007/07/06/3193.aspx#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://blogs.x2line.com/al/comments/commentRss/3193.aspx</wfw:commentRss><trackback:ping>http://blogs.x2line.com/al/services/trackbacks/3193.aspx</trackback:ping><description>&lt;p&gt;Sometimes it is a common task in .NET applications to start some command-line process using &lt;b&gt;System.Diagnostics.Process&lt;/b&gt;. Like so:&lt;/p&gt;&lt;br /&gt;
&lt;pre&gt;
Process proc = new Process();
proc.StartInfo.FileName = "mycommand.cmd";
proc.Start();
&lt;/pre&gt;&lt;br /&gt;
&lt;p&gt;However it is a bit more complicated task to determine when the Process exited or the command finished its work. 2 handy properties of Process would help: &lt;i&gt;HasExited&lt;/i&gt; and &lt;i&gt;WaitForExit&lt;/i&gt;:&lt;/p&gt;&lt;br /&gt;
&lt;pre&gt;
do 
{              
    if (!proc.HasExited)
    {
        proc.Refresh();
    }
}
while (!proc.WaitForExit(1000));

// exited here - do work
&lt;/pre&gt;&lt;br /&gt;
&lt;p&gt;Enjoy :)&lt;/p&gt;&lt;img src ="http://blogs.x2line.com/al/aggbug/3193.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>Anatoly Lubarsky</dc:creator><title>How to Monitor Network Connectivity in .NET</title><link>http://blogs.x2line.com/al/archive/2007/06/08/3148.aspx</link><pubDate>Fri, 08 Jun 2007 20:07:00 GMT</pubDate><guid>http://blogs.x2line.com/al/archive/2007/06/08/3148.aspx</guid><wfw:comment>http://blogs.x2line.com/al/comments/3148.aspx</wfw:comment><comments>http://blogs.x2line.com/al/archive/2007/06/08/3148.aspx#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://blogs.x2line.com/al/comments/commentRss/3148.aspx</wfw:commentRss><trackback:ping>http://blogs.x2line.com/al/services/trackbacks/3148.aspx</trackback:ping><description>&lt;p&gt;There is a common problem with smart client applications that they need to implement monitoring network connectivity. Common scenario - if the computer is connected - send data to the server, otherwise - serialize data to disk, then wait for network connectivity becomes available and when the network is available - send serialized data to the server in the background.&lt;/p&gt;&lt;br&gt;
&lt;p&gt;.NET 2.0 introduced &lt;i&gt;System.Net.NetworkInformation&lt;/i&gt; with &lt;b&gt;NetworkAvailabilityChanged&lt;/b&gt; event, so there is no need to reinvent network monitor behavior by hand any more :)&lt;/p&gt;&lt;br&gt;
&lt;p&gt;Use the right namespace :)&lt;/p&gt;&lt;br&gt;
&lt;pre&gt;using System.Net.NetworkInformation;&lt;/pre&gt;&lt;br&gt;
&lt;p&gt;Now it is possible to check connectivity on demand...&lt;/p&gt;&lt;br&gt;
&lt;pre&gt;bool connected = NetworkInterface.GetIsNetworkAvailable();&lt;/pre&gt;
&lt;p&gt;Or subscribe to event in some place....&lt;/p&gt;&lt;br&gt;
&lt;pre&gt;NetworkChange.NetworkAvailabilityChanged += OnAvaiabilityChanged;&lt;/pre&gt;&lt;br&gt;
&lt;p&gt;Implement like so:&lt;/p&gt;&lt;br&gt;
&lt;pre&gt;
private void OnAvaiabilityChanged(object sender, 
    NetworkAvailabilityEventArgs args)
{
    this.UpdateStatus(args.IsAvailable);
}

private void UpdateStatus(bool connected)
{
    if (connected)
    {
        ...
    }
    else
    {
        ...
    }
}
&lt;/pre&gt;&lt;br&gt;
&lt;p&gt;Enjoy :)&lt;/p&gt;&lt;img src ="http://blogs.x2line.com/al/aggbug/3148.aspx" width = "1" height = "1" /&gt;</description></item></channel></rss>