WCF服务编程读书笔记(8):并发管理

Example 8-1. Manual synchronization using fragmented locking

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.Transactions;

namespace WCFServiceProgramming.Library
{
    [ServiceContract(SessionMode = SessionMode.Required)]
    public interface IMyContract
    {
        void MyMethod();
    }

    [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
    public class MyService : IMyContract
    {
        int[] _numbers;
        List<string> _names;

        [OperationBehavior(TransactionScopeRequired = true)]
        public void MyMethod()
        {
            lock (_numbers)
            {
                //...
            }

            // Don't access members here

            lock (_names)
            {
                //...
            }
        }
    }
}
View Code

Example 8-2. Configure for reentrancy to allow callbacks

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.Transactions;

namespace WCFServiceProgramming.Library
{
    [ServiceContract(CallbackContract = typeof(IMyContractCallback))]
    public interface IMyContract
    {
        [OperationContract]
        void MyMethod();
    }

    public interface IMyContractCallback
    {
        [OperationContract]
        void OnCallback();
    }

    [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant)]
    public class MyService : IMyContract
    {
        public void MyMethod()
        {
            IMyContractCallback callback = 
                OperationContext.Current.GetCallbackChannel<IMyContractCallback>();

            callback.OnCallback();
        }
    }
}
View Code

Example 8-3. Using the service type as a shared lock

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.Transactions;

namespace WCFServiceProgramming.Library
{
    [ServiceContract]
    public interface IMyContract
    {
        [OperationContract]
        void MyMethod();
    }

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, 
        ConcurrencyMode = ConcurrencyMode.Multiple)]
    public class MyService : IMyContract
    {
        public void MyMethod()
        {
            lock (typeof(MyService))
            {
                MyResource.DoWork();
            }
        }
    }

    static class MyResource
    {
        public static void DoWork()
        {
            lock (typeof(MyService))
            { }
        }
    }
}
View Code

Example 8-4. Calling a resource on the correct synchronization context

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.Transactions;
using System.Threading;

namespace WCFServiceProgramming.Library
{
    [ServiceContract]
    public interface IMyContract
    {
        [OperationContract]
        void MyMethod();
    }

    class MyResource
    {
        public SynchronizationContext MySynchronizationContext { get; }

        public int DoWork()
        {
            return 0;
        }
    }

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, 
        ConcurrencyMode = ConcurrencyMode.Multiple)]
    public class MyService : IMyContract
    {
        MyResource GetResource()
        {
            return new MyResource();
        }

        public void MyMethod()
        {
            MyResource resource = GetResource();
            SynchronizationContext context = resource.MySynchronizationContext;

            int result = 0;
            SendOrPostCallback doWork = delegate
            {
                result = resource.DoWork();
            };

            context.Send(doWork, null);
        }
    }
}
View Code

Example 8-5. Encapsulating the synchronization context

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.Transactions;
using System.Threading;

namespace WCFServiceProgramming.Library
{
    [ServiceContract]
    public interface IMyContract
    {
        [OperationContract]
        void MyMethod();
    }

    class MyResource
    {
        public int DoWork()
        {
            int result = 0;

            SendOrPostCallback doWork = delegate
            {
                result = DoWorkInternal();
            };

            MySynchronizationContext.Send(doWork, null);
            return result;
        }

        SynchronizationContext MySynchronizationContext { get; }

        int DoWorkInternal()
        {
            return 0;
        }
    }

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    public class MyService : IMyContract
    {
        MyResource GetResource()
        {
            return new MyResource();
        }

        public void MyMethod()
        {
            MyResource resource = GetResource();
            int result = resource.DoWork();
        }
    }
}
View Code

Example 8-6. Using the form synchronization context

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Diagnostics;
using System.ServiceModel;

namespace WCFServiceProgramming.Library
{
    [ServiceContract]
    interface IFormManager
    {
        [OperationContract]
        void IncrementLabel();
    }

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    class MyService : IFormManager
    {
        public void IncrementLabel()
        {
            MyForm form = Application.OpenForms[0] as MyForm;
            Debug.Assert(form != null);

            SendOrPostCallback callback = delegate
            {
                form.Counter++;
            };

            form.MySynchronizationContext.Send(callback, null);
                 
        }
    }

    partial class MyForm : Form
    {
        Label _counterLabel;
        SynchronizationContext _synchronizationContext;

        public MyForm()
        {
            //InitializeComponent();
            _synchronizationContext = SynchronizationContext.Current;
            Debug.Assert(_synchronizationContext != null);
        }

        public SynchronizationContext MySynchronizationContext
        {
            get
            {
                return _synchronizationContext;
            }
        }

        public int Counter
        {
            get
            {
                return Convert.ToInt32(_counterLabel.Text);
            }
            set
            {
                _counterLabel.Text = value.ToString();
            }
        }
    }
}
View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WCFServiceProgramming.Library;
using System.ServiceModel;

namespace WCFServiceProgramming.Host
{
    class Program
    {
        static void Main(string[] args)
        {
            ServiceHost host = new ServiceHost(typeof(MyService));
            host.Open();

            Application.Run(new MyForm());

            host.Close();
        }
    }
}
View Code

Example 8-7. Encapsulating the synchronization context

Example 8-8. Using a safe control

Example 8-9. Hosting the service by the form

Example 8-10. Storing form reference in a thread-relative static variable

Example 8-11. Hosting on multiple UI threads

Example 8-12. Form as a singleton service

Example 8-13. Implementing FormHost<F>

Example 8-14. Installing AffinitySynchronizer

Example 8-15. Adding thread affinity support to ServiceHost<T>

Example 8-16. Implementing ThreadAffinityBehaviorAttribute

Example 8-17. Implementing ThreadAffinityHelper

Example 8-18. Manually synchronizing the callback with ConcurrencyMode.Single

Example 8-19. Manually synchronizing callback with ConcurrencyMode.Multiple

Example 8-20. Relying on the UI synchronization context for callbacks

Example 8-21. Explicitly opening a proxy to establish synchronization context

Example 8-22. Avoiding callback deadlock on the UI thread

Example 8-23. Setting custom synchronization context for the callback

Example 8-24. Applying the CallbackThreadAffinityBehavior attribute

Example 8-25. Implementing CallbackThreadAffinityBehaviorAttribute

Example 8-26. Asynchronous contract and proxy

Example 8-27. Simple asynchronous execution sequence

Example 8-28. UsingIasyncResult.AsyncWaitHandle to block until completion

Example 8-29. Using WaitOne( ) to specify wait timeout

Example 8-30. Waiting for completion of multiple methods

Example 8-31. Managing asynchronous call with a completion callback

Example 8-32. Passing an additional parameter using a state object

Example 8-33. Relying on completion callback synchronization context

原文地址:https://www.cnblogs.com/thlzhf/p/2779859.html