Friday, June 28, 2013

WCF Timeouts explained

Found this good explanation for the various timeouts in WCF and which ones get used on the client and which get used on server.

Brief summary of binding timeout knobs...

Client side:

  • SendTimeout is used to initialize the OperationTimeout, which governs the whole interaction for sending a message (including receiving a reply message in a request-reply case).  This timeout also applies when sending reply messages from a CallbackContract method.
  • OpenTimeout and CloseTimeout are used when opening and closing channels (when no explicit timeout value is passed).
  • ReceiveTimeout is not used.

Server side:

  • Send, Open, and Close Timeout same as on client (for Callbacks).
  • ReceiveTimeout is used by ServiceFramework layer to initialize the session-idle timeout.

From: http://social.msdn.microsoft.com/Forums/vstudio/en-US/84551e45-19a2-4d0d-bcc0-516a4041943d/explaination-of-different-timeout-types

Monday, June 24, 2013

Using the Adobe Pdf Reader control in WPF

Important: This will not work if your application targets 64 bit. It will only work as a 32bit app as the AcroPdf.dll is a 32 bit dll.

1. Create a WPF Control Library

2. Add a Windows Forms user control

3. Open the user-control form.

4. In the toolbox, right click and choose “Choose Items…”

5. On the “COM Components” tab, select “Adobe PDF Reader”

image

6. Drag the “Adobe PDF Reader” from the toolbox on the user-control.
Name the control that was added on to the form as "axAcroPdf”

7. Make sure the Anchors are set to “Top, Left” and that Dock is set to “Fill”
image

8. Add the following code to the code behind:

		private AxAcroPDFLib.AxAcroPDF AdobeAcrobatPDfControl
		{
			get
			{
				return this.axAcroPDF;
			}
		}
 
		public void LoadFile(string pdfFilePath)
		{
			AdobeAcrobatPDfControl.LoadFile(pdfFilePath);
		}

8. Create a WPF UserControl. Name it WpfAcrobatCtrl.

9. Drag a WindowsFormsHost WPF control onto the design surface.

10. Set the following properties on the WindowsFormsHost control:
Width and Height to Auto
HorizontalAlignment and VerticalAlignment to Stretch
Name: wpfWindowsFormsHostCtrl.

11. Add the following code to the code behind of the WPF control:

public static readonly DependencyProperty FilePathProperty
			= DependencyProperty.Register("FilePath", typeof(string), typeof(WpfAcrobatCtrl), (PropertyMetadata)new FrameworkPropertyMetadata((object)null, new PropertyChangedCallback(WpfAcrobatCtrl.FilePathChanged)));
 
 
		private string _filePath = string.Empty;
		private CustomAcrobatCtrl _customAcrobatCtrl;
	
		
		private static void FilePathChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
			((WpfAcrobatCtrl)d).FilePathChanged((string)e.OldValue, (string)e.NewValue);
			CommandManager.InvalidateRequerySuggested();
		}
 
		public WpfAcrobatCtrl()
		{
			InitializeComponent();
			_customAcrobatCtrl = new CustomAcrobatCtrl();
			wpfWindowsFormsHostCtrl.Child = _customAcrobatCtrl;
 
		}
 
		public string FilePath
		{
			get
			{
				return _filePath;
			}
			set
			{
				this.SetValue(FilePathProperty, value);
			}
		}
 
 
		private void FilePathChanged(string oldFilePath, string newFilePath)
		{
			_filePath = newFilePath;
			_customAcrobatCtrl.LoadFile(_filePath);
		}

12. Create a new WPF Window.

13. Drag and drop the WpfAcrobatCtrl onto the design surface.

14. Set the file-path in XAML or code-behind.

Eg: wpfAcrobatCtrl.FilePath = "C:\\test.pdf";

or in XAML: <WpfAcrobat:WpfAcrobatCtrl x:Name="wpfAcrobatCtrl" Margin="0" FilePath="C:\\test.pdf"/>

That’s all!

Note: The above code adds a little extra stuff for the dependency property “FilePath”. This allows for setting the file path via XAML (which was important for me as I needed to be able bind to the property).

Note 2: If you try and use the AcroPdf.dll in a 64 bit app, you will get the following error: {"Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG))"}

Tuesday, June 11, 2013

C# - Why you must never lock on this

You should never lock on “this” if this points to an instance of a publicly accessible class. The reason is that if the class is publicly accessible, then you have no control over whether someone else who uses your class, uses the instance for locking. And if they do lock an instance of your class, then you will end up in a dead-lock.

Here is some simple code to illustrate this:

using System.Threading.Tasks;

void Main()
{
    ClassTest test = new ClassTest();
    lock(test) //locking on the instance of ClassTest
    {
        Parallel.Invoke (new Action[]{() => test.DoWorkUsingThisLock(1)});
    }
}

public class ClassTest
{
    public void DoWorkUsingThisLock(int i)
    {
        Console.WriteLine("Before ClassTest.DoWorkUsingThisLock " + i);
        lock(this) //this is bad - this will never end - you have been deadlocked!
        {
            Console.WriteLine("ClassTest.DoWorkUsingThisLock " + i);
            Thread.Sleep(1000);
        }
        Console.WriteLine("ClassTest.DoWorkUsingThisLock Done " + i);
    }
}

From MSDN:

In general, avoid locking on a public type, or instances beyond your code's control. The common constructs lock (this), lock (typeof (MyType)), and lock ("myLock") violate this guideline:

  • lock (this) is a problem if the instance can be accessed publicly.

  • lock (typeof (MyType)) is a problem if MyType is publicly accessible.

  • lock("myLock") is a problem because any other code in the process using the same string, will share the same lock.

References:

Lock Statement (MSDN)