Async/Await Snipped: Ensure one-time execution

Think if you have some initialization code that you want to execute only once. Multiple threads could call in. Your code uses async and await keywords and you want to be able to await until it completes…

        Task _workerTask;

        object _workerSyncRoot = new object();

        async Task EnsureWorkerDoneAsync()
        {
            // ensure that the worker is executed only once
            lock (_workerSyncRoot)
                if (_workerTask == null)
                    _workerTask = WorkerAsync();
            
            // await the worker, if it has not
            if (_workerTask.Status != TaskStatus.RanToCompletion)
                await _workerTask;
        }
Tagged , , ,

Async/Await Snipped: Avoid multiple calls by using delays

When you work with async and await keywords in C#. You sometimes want to avoid unnecessary calls, that are caused by multi-threading. Here is a simple snipped that works fine…

Scenario: Last Wins

        Task _delayTask;

        async void StartWithDelay()
        {
            // keep a local copy and a member copy of the task
            Task delayTask = _delayTask = Task.Delay(1000);

            // await the delay
            await delayTask;

            // is it still the same task (or is there a new one)
            if(delayTask == _delayTask) 
            {
                // do your work here...
            }
        }
Tagged , , ,

Design-Time Dictionary

In my current VSTO project I need a design-time only resource dictionary. I found the following solution and modified it just a bit.

http://social.technet.microsoft.com/wiki/contents/articles/23287.trick-to-use-a-resourcedictionary-only-when-in-design-mode.aspx

I had some problems with the DesignMode detection in that sample so I used the version here…

http://bernhardelbl.wordpress.com/2011/06/16/howto-detecting-design-mode-in-wpf-asp-net-and-windows-forms-applications/

 


public class ResourceDictionary : System.Windows.ResourceDictionary
{
/// <summary>
/// Gets or sets the uniform resource identifier (URI) to load resources from.
/// </summary>
/// <returns>The source location of an external resource dictionary. </returns>
public new Uri Source
{
get
{
if (Util.DesignMode)
return base.Source;
else
return null;
}

set
{
if (Util.DesignMode)
{
base.Source = value;
}
}
}
}

Encrypt and Decrypted a String using symetric key

Encrypt and decrypt a string value to a encrypted base64 string and back by Rijndael.

You can use it as snipped. The keys are hard coded for simplification…


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace CryptoTest
{
/// <summary>
/// Can encrypt and decrypt a string
/// </summary>
public class CryptoService
{
static byte[] Key = new Guid("{1F2D888B-9566-4F99-92DA-13C37A7ACBDA}").ToByteArray();
static byte[] IV = new Guid("{2A4261C5-A53E-47B3-BF4A-97D944C93813}").ToByteArray();

public string EncryptString(string plainText)
{
// Instantiate a new RijndaelManaged object to perform string symmetric encryption
using (var rijndaelCipher = new RijndaelManaged())
{
// Set key and IV

rijndaelCipher.Key = Key;
rijndaelCipher.IV = IV;

// Instantiate a new MemoryStream object to contain the encrypted bytes
using (var memoryStream = new MemoryStream())
{
// Instantiate a new encryptor from our RijndaelManaged object
using (var rijndaelEncryptor = rijndaelCipher.CreateEncryptor())
{

// Instantiate a new CryptoStream object to process the data and write it to the
// memory stream
using (var cryptoStream = new CryptoStream(memoryStream, rijndaelEncryptor, CryptoStreamMode.Write))
{
// Convert the plainText string into a byte array
byte[] plainBytes = Encoding.UTF8.GetBytes(plainText);

// Encrypt the input plaintext string
cryptoStream.Write(plainBytes, 0, plainBytes.Length);

// Complete the encryption process
cryptoStream.FlushFinalBlock();

// Convert the encrypted data from a MemoryStream to a byte array
byte[] cipherBytes = memoryStream.ToArray();

// Convert the encrypted byte array to a base64 encoded string
string cipherText = Convert.ToBase64String(cipherBytes, 0, cipherBytes.Length);

// Return the encrypted data as a string
return cipherText;
}
}
}
}
}


public string DecryptString(string cipherText)
{
// Instantiate a new RijndaelManaged object to perform string symmetric encryption
using (RijndaelManaged rijndaelCipher = new RijndaelManaged())
{
// Set key and IV
rijndaelCipher.Key = Key;
rijndaelCipher.IV = IV;

// Instantiate a new MemoryStream object to contain the encrypted bytes
using (var memoryStream = new MemoryStream())
{
// Instantiate a new encryptor from our RijndaelManaged object
using (var rijndaelDecryptor = rijndaelCipher.CreateDecryptor())
{
// Instantiate a new CryptoStream object to process the data and write it to the
// memory stream
using (var cryptoStream = new CryptoStream(memoryStream, rijndaelDecryptor, CryptoStreamMode.Write))
{

// Will contain decrypted plaintext
string plainText = String.Empty;

// Convert the ciphertext string into a byte array
byte[] cipherBytes = Convert.FromBase64String(cipherText);

// Decrypt the input ciphertext string
cryptoStream.Write(cipherBytes, 0, cipherBytes.Length);

// Complete the decryption process
cryptoStream.FlushFinalBlock();

// Convert the decrypted data from a MemoryStream to a byte array
byte[] plainBytes = memoryStream.ToArray();

// Convert the encrypted byte array to a base64 encoded string
plainText = Encoding.UTF8.GetString(plainBytes, 0, plainBytes.Length);

// Return the encrypted data as a string
return plainText;
}
}
}
}
}
}
}

String to Guid with MD5 hashes for .NET and SQL Server

If you need to convert a string value to Guid you can use MD5 hashes. They are always having a length of 128 bits and therefore can be converted to a Guid.

Why you may want to do this?

In my project I’m having a big database containing some very long text values. I needed a way to quickly compare and query them. In Sql Server indexed columns does have a maximun length and in my case the limit was exceeded. Storing the hashes of big text values in the database is a good option for that. You can add an index to the Guid and query quickly.

.NET C#

This example converts a string to Guid in C#

        /// <summary>
        /// Convert string to Guid
        /// </summary>
        /// <param name="value">the string value</param>
        /// <returns>the Guid value</returns>
        public static Guid ConvertToMd5HashGUID(string value)
        {
            // convert null to empty string - null can not be hashed
            if (value == null)
                value = string.Empty;

            // get the byte representation
            var bytes = Encoding.Default.GetBytes(value);

            // create the md5 hash
            MD5 md5Hasher = MD5.Create();
            byte[] data = md5Hasher.ComputeHash(bytes);

            // convert the hash to a Guid
            return new Guid(data);
        }

SQL

SELECT CAST(HASHBYTES('MD5', ISNULL('Test', '')) AS UNIQUEIDENTIFIER)

Turn off Visual Studio Attach security warning when debugging IIS

I found this post and it works. But note that you need to close Visual Studio before you update the registry, otherwise your changes will be overriden.

http://stackoverflow.com/questions/1414769/turn-off-visual-studio-attach-security-warning-when-debugging-iis

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\12.0\Debugger]
"DisableAttachSecurityWarning"=dword:00000001

[HKEY_CURRENT_USER\Software\Wow6432Node\Microsoft\VisualStudio\12.0\Debugger]
"DisableAttachSecurityWarning"=dword:00000001

Version 12 means Visual Studio 2013

Windows Ribbon for WinForms in Visual Studio 2013

The Windows Ribbon project is still working in Visual Studio 2013. Now I will show you the steps I did to get it working.

Download and install Windows 8.1 SDK

Windows 7 SDK is also enough.

Bild 156

Download the Latest Ribbon Sources

http://windowsribbon.codeplex.com/SourceControl/latest

Bild 152

Get the RibbonGenerator compiling

The download is below. You do not need this.

Bild 153

Microsoft.VisualStudio.Shell not found?

Bild 154 Bild 155

 Download Visual Studio 2013 SDK

Bild 157

Bild 158

Bild 159

Switch the target of the RibbonGenerator

Bild 160

Bild 161

Now it should compile.

Download the Ribbon Generator for Visual Studio 2013

Note that it this one will only work for VS 2013. Download contains RibbonGenerator binaries and source.

http://sdrv.ms/1ewICJN

Register the Ribbon Generator (Custom Tool)

- Create a .reg file and import it. This one will only work with VS 2013 and a x64 Windows.

Windows Registry Editor Version 5.00</pre>
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\12.0\CLSID\{B64582D9-A489-42F4-BA55-BB6039D82916}]
@="RibbonGenerator"
"InprocServer32"="C:\\WINDOWS\\system32\\mscoree.dll"
"Class"="RibbonGenerator.CustomTool"
"Assembly"="RibbonGenerator, Version=1.0.1.0, Culture=neutral, PublicKeyToken=3cf107c5d7e68b1c"
"ThreadingModel"="Both"

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\12.0\Generators\{164B10B9-B200-11D0-8C61-00A0C91E29D5}\RibbonGenerator]
@="Ribbon Generator"
"CLSID"="{B64582D9-A489-42F4-BA55-BB6039D82916}"
"GeneratesDesignTimeSource"=dword:00000001

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\12.0\Generators\{E6FDF8B0-F3D1-11D4-8576-0002A516ECE8}\RibbonGenerator]
@="Ribbon Generator"
"CLSID"="{B64582D9-A489-42F4-BA55-BB6039D82916}"
"GeneratesDesignTimeSource"=dword:00000001

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\12.0\Generators\{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}\RibbonGenerator]
@="Ribbon Generator"
"CLSID"="{B64582D9-A489-42F4-BA55-BB6039D82916}"
"GeneratesDesignTimeSource"=dword:00000001
<pre>

- Open Cmd as Administrator

- Use the correct version of gacutil.

“C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools\gacutil.exe” -i “C:\…\RibbonGenerator.dll”

Check RibbonGenerator Registration

Check that Ribbon Generator is working correctly.

- Open the Ribbon-cs.sln solution

- Right-click on RibbonMarkup.xml and click Run Custom Tool

Bild 167

The following screenshot means, you have done a mistake in the previous steps.

Bild 166

Update the template.bat

No error occurred, but still not work? Check that all the tools are on your hard disc. Check all pathes to be  correct …

C:\Users\<user>\AppData\Local\RibbonGenerator\Template.bat”


"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Bin\UICC.exe" "{XmlFilename}" "{BmlFilename}" /res:"{RcFilename}"
"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Bin\rc.exe" /v "{RcFilename}"
cmd /c "("%VS120COMNTOOLS%..\..\VC\bin\vcvars32.bat") && ("%VS120COMNTOOLS%..\..\VC\bin\link.exe" /VERBOSE /NOENTRY /DLL /OUT:"{DllFilename}" "{ResFilename}")"

Other Ribbon Posts

Quickstart Tutorial: Windows Ribbon for WinForms
RibbonGenerator Details: Windows Ribbon for WinForms
RibbonGenerator for Visual Studio 2010 Express Editions: Windows Ribbon for WinForms

Follow

Get every new post delivered to your Inbox.