/// <summary>
        /// Determina l'avvio della procedura che permette di inviare il task specificato al servizio di elaborazione,
        /// di verificarne periodicamente il completamento e di eseguire alla fine il download dei relativi risultati
        /// eventualmente prodotti.
        /// </summary>
        /// <remarks>
        /// Prima di invocare questo metodo, è necessario utilizzare il metodo SetTaskData per poter impostare i dati
        /// relativi al task da elaborare.
        /// Inoltre, questo metodo non dovrebbe essere invocato sul thread della UI, in quanto la verifica periodica
        /// del completamento dell'elaborazione blocca tale thread per l'intervallo di polling specificato.
        /// </remarks>
        public void Start()
        {
            if (m_Proxy == null)
            {
                try
                {
                    RaiseTaskExecutionProgress(TaskRequestState.InitializingProxy, null);
                    m_Proxy = new ProcessingServiceClient(m_Binding, m_Endpoint);
                    m_Proxy.Open();
                    RaiseTaskExecutionProgress(TaskRequestState.ProxyInitialized, null);

                    RaiseTaskExecutionProgress(TaskRequestState.SendingRequest, null);
                    m_TaskRequestId = m_Proxy.SubmitData(m_TaskData);
                    RaiseTaskExecutionProgress(TaskRequestState.RequestSent, null);

                    bool completed = false;
                    while (!completed)
                    {
                        m_PollingWaitHandle.WaitOne(m_PollingInterval);
                        TaskState ts = m_Proxy.GetState(m_TaskRequestId);

                        switch (ts)
                        {
                        case TaskState.Completed:
                            RaiseTaskExecutionProgress(TaskRequestState.DownloadingResults, null);
                            m_TaskResults = m_Proxy.GetResults(m_TaskRequestId);
                            RaiseTaskExecutionProgress(TaskRequestState.ResultsDownloaded, null);
                            RaiseTaskExecutionCompleted(false, null, m_TaskResults);
                            completed = true;
                            break;

                        case TaskState.None:
                            completed = true;
                            break;

                        default:
                            completed = false;
                            break;
                        }
                    }

                    RaiseTaskExecutionProgress(TaskRequestState.DisposingProxy, null);
                    m_Proxy.Close();
                    RaiseTaskExecutionProgress(TaskRequestState.ProxyDisposed, null);
                }
                catch (Exception ex)
                {
                    HandleError(ex);
                }
            }
        }
        /// <summary>
        /// Permette di gestire un errore verificatosi durante la procedura e restituisce true se è stata gestita,
        /// altrimenti false se non è stato necessario gestirlo poiché di fatto non è avvenuta alcun errore.
        /// </summary>
        /// <param name="error">l'eccezione che ha provocato l'errore</param>
        private void HandleError(Exception error)
        {
            if (error != null)
            {
                TaskRequestState state;
                if (m_CommunicationErrorsMapping.TryGetValue(error.GetType(), out state))
                {
                    RaiseTaskExecutionProgress(state, error);

                    m_Proxy.Abort();
                    RaiseTaskExecutionProgress(TaskRequestState.ProxyDisposed, error);

                    m_Proxy = null;
                }
                else
                {
                    if (error is FaultException <ServiceFault> )
                    {
                        RaiseTaskExecutionProgress(TaskRequestState.OperationError, error);

                        RaiseTaskExecutionProgress(TaskRequestState.DisposingProxy, error);
                        m_Proxy.Close();
                    }
                    else
                    {
                        RaiseTaskExecutionProgress(TaskRequestState.UnknownError, error);

                        m_Proxy.Abort();
                        RaiseTaskExecutionProgress(TaskRequestState.ProxyDisposed, error);

                        m_Proxy = null;
                    }
                }

                RaiseTaskExecutionCompleted(false, error, null);
            }
        }
        /// <summary>
        /// Determina l'avvio della procedura che permette di inviare il task specificato al servizio di elaborazione,
        /// di verificarne periodicamente il completamento e di eseguire alla fine il download dei relativi risultati
        /// eventualmente prodotti.
        /// </summary>
        /// <remarks>
        /// Prima di invocare questo metodo, è necessario utilizzare il metodo SetTaskData per poter impostare i dati
        /// relativi al task da elaborare.
        /// Inoltre, questo metodo non dovrebbe essere invocato sul thread della UI, in quanto la verifica periodica
        /// del completamento dell'elaborazione blocca tale thread per l'intervallo di polling specificato.
        /// </remarks>
        public void Start()
        {
            if (m_Proxy == null)
            {
                try
                {
                    RaiseTaskExecutionProgress(TaskExecutionState.InitializingProxy, null);
                    m_Proxy = new ProcessingServiceClient(m_Binding, m_Endpoint);
                    m_Proxy.Open();
                    RaiseTaskExecutionProgress(TaskExecutionState.ProxyInitialized, null);

                    RaiseTaskExecutionProgress(TaskExecutionState.SendingRequest, null);
                    m_TaskRequestId = m_Proxy.SubmitData(m_TaskData);
                    RaiseTaskExecutionProgress(TaskExecutionState.RequestSent, null);

                    bool completed = false;
                    while (!completed)
                    {
                        m_PollingWaitHandle.WaitOne(m_PollingInterval);
                        TaskState ts = m_Proxy.GetState(m_TaskRequestId);

                        switch (ts)
                        {
                            case TaskState.Completed:
                                RaiseTaskExecutionProgress(TaskExecutionState.DownloadingResults, null);
                                m_TaskResults = m_Proxy.GetResults(m_TaskRequestId);
                                RaiseTaskExecutionProgress(TaskExecutionState.ResultsDownloaded, null);
                                completed = true;
                                break;

                            case TaskState.None:
                                completed = true;
                                break;

                            default:
                                completed = false;
                                break;
                        }
                    }

                    RaiseTaskExecutionProgress(TaskExecutionState.DisposingProxy, null);
                    m_Proxy.Close();
                    RaiseTaskExecutionProgress(TaskExecutionState.ProxyDisposed, null);

                    RaiseTaskExecutionCompleted(false, null, m_TaskResults);
                }
                catch (Exception ex)
                {
                    HandleError(ex);
                }
            }
        }