Exemplo n.º 1
0
        /// <summary>
        /// Captures received messages and waits until dispatcher permission has been granted.
        /// </summary>
        /// <param name="proxy">The received messages proxy.</param>
        /// <param name="cancelToken">The cancellation token.</param>
        public static async Task WaitForPermissionAsync(DispatcherProxy proxy, CancellationToken cancelToken = default(CancellationToken))
        {
            TaskCompletionSource <object> tcs = new TaskCompletionSource <object>();

            proxy.SetTarget(new PermissionWaiter(tcs));
            try {
                using (cancelToken.Register(() => tcs.TrySetCanceled())) {
                    await tcs.Task;
                }
            } finally {
                proxy.SetTarget(null);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Captures received messages and waits until dispatcher permission has been granted.
        /// </summary>
        /// <param name="proxy">The received messages proxy.</param>
        /// <param name="cancelToken">The cancellation token.</param>
        public static async Task <int> WaitForSubAreaNumberAsync(DispatcherProxy proxy, CancellationToken cancelToken = default(CancellationToken))
        {
            TaskCompletionSource <int> tcs = new TaskCompletionSource <int>();

            proxy.SetTarget(new SubAreaNumberWaiter(tcs));
            try {
                using (cancelToken.Register(() => tcs.TrySetCanceled())) {
                    return(await tcs.Task);
                }
            } finally {
                proxy.SetTarget(null);
            }
        }
Exemplo n.º 3
0
            /// <summary>
            /// The implementation of Execute.
            /// </summary>
            /// <param name="welcomeWindow">The welcome window, which is closed if login succeeds.</param>
            /// <param name="cancelToken">A token used to cancel connection.</param>
            private async Task ExecuteAsync(Window welcomeWindow, CancellationToken cancelToken)
            {
                Debug.Assert(Parent.ConnectionProgress == EConnectionProgress.None);

                // Create the objects.
                NetTcpBinding   binding          = new NetTcpBinding(SecurityMode.None);
                DispatcherProxy proxy            = new DispatcherProxy();
                InstanceContext ic               = new InstanceContext(proxy);
                string          uri              = BuildUri(Parent.ConnectToLocal ? "localhost" : Parent.RemoteHostname).ToString();
                DuplexChannelFactory <IRun8> dcf = new DuplexChannelFactory <IRun8>(ic, binding, uri);

                Parent.ConnectionProgress = EConnectionProgress.Connecting;
                dcf.Open();
                if (dcf.State == CommunicationState.Faulted)
                {
                    Parent.LastErrorMessage   = "Failed to connect.";
                    Parent.ConnectionProgress = EConnectionProgress.None;
                    return;
                }
                Run8Wrapper run8 = new Run8Wrapper(dcf.CreateChannel());

                // Send the DispatcherConnected message, allowing the operation to be cancelled.
                {
                    Task connectTask = null;
                    try {
                        TaskCompletionSource <object> cancelTCS = new TaskCompletionSource <object>();
                        connectTask = run8.DispatcherConnectedAsync();
                        using (cancelToken.Register(() => cancelTCS.TrySetCanceled())) {
                            await await Task.WhenAny(connectTask, cancelTCS.Task);
                        }
                    } catch (OperationCanceledException) {
                        dcf.Abort();
                        Parent.ConnectionProgress = EConnectionProgress.None;
                        try {
                            await connectTask;
                        } catch (CommunicationException) {
                            // Swallow.
                        }
                        return;
                    } catch (CommunicationException exp) {
                        dcf.Abort();
                        Parent.LastErrorMessage   = "Failed to connect: " + exp.Message;
                        Parent.ConnectionProgress = EConnectionProgress.None;
                        return;
                    }
                }

                // Wait until Run8 grants us permission, allowing the operation to be cancelled.
                Parent.ConnectionProgress = EConnectionProgress.WaitingForPermission;
                try {
                    await PermissionWaiter.WaitForPermissionAsync(proxy, cancelToken);
                } catch (OperationCanceledException) {
                    dcf.Abort();
                    Parent.ConnectionProgress = EConnectionProgress.None;
                    return;
                }

                // Wait until Run8 sends us a message with a route number in it so we can look up in the database what data to load.
                Parent.ConnectionProgress = EConnectionProgress.WaitingForData;
                int route;

                try {
                    route = await SubAreaNumberWaiter.WaitForSubAreaNumberAsync(proxy, cancelToken);
                } catch (OperationCanceledException) {
                    dcf.Abort();
                    Parent.ConnectionProgress = EConnectionProgress.None;
                    return;
                }

                // Create the world.
                World.World world;
                try {
                    world = new World.World(run8, route);
                } catch (World.World.UnrecognizedRegionException) {
                    dcf.Abort();
                    Parent.LastErrorMessage   = "Unrecognized route ID " + route;
                    Parent.ConnectionProgress = EConnectionProgress.None;
                    return;
                }
                proxy.SetTarget(world);

                // Done! Launch the main window.
                Parent.ConnectionProgress = EConnectionProgress.None;
                MainWindow mw = new MainWindow(new MainViewModel(world));

                Application.Current.MainWindow = mw;
                mw.Show();
                welcomeWindow.Close();
            }