public ManagedBitmap ResizeGDI(ManagedBitmap source, int targetWidth, int targetHeight, Profile profile) { EnsureStarted(profile); ManagedBitmap result; string mapId; int width, height; Profile serverProfile; bool succeeded = false; profile.Push("Remote call"); ClientServerCommunication.SendMessage( null /*log*/, channel, ClientServerCommunication.Commands.ResizeGDI, new object[] { (int)Thread.CurrentThread.Priority, (string)source.BackingName, (int)source.Width, (int)source.Height, (int)targetWidth, (int)targetHeight }); try { ClientServerCommunication.WaitForPending(channel, out serverProfile, out mapId, out width, out height); profile.Add(serverProfile); result = new ManagedBitmap32(width, height, mapId); succeeded = true; } catch (ClientServerCommunication.RemoteException) { result = ManagedBitmap.CreateFromGDI(new Bitmap(Properties.Resources.InvalidPlaceHolder)); } profile.Pop(); if (succeeded) { profile.Push("Remote call"); ClientServerCommunication.SendMessage( null /*log*/, channel, ClientServerCommunication.Commands.Clear, null); ClientServerCommunication.WaitForDone(channel, out serverProfile); profile.Add(serverProfile); profile.Pop(); } return(result); }
private const bool Logging = true; // TODO: turn off public static int RunServer(string pipeName) { TextWriter log; if (Logging) { int i = 0; while (true) { try { log = new StreamWriter(Path.Combine(Path.GetTempPath(), String.Concat("ImageServerLog-", i, ".log"))); } catch (Exception) { i++; continue; } break; } log = TextWriter.Synchronized(log); } ManagedBitmap currentBitmap = null; try { ThreadPriority savedThreadPriority = Thread.CurrentThread.Priority; if (log != null) { log.WriteLine("Connecting to pipe {0}", pipeName); log.Flush(); } using (NamedPipeClientStream channel = new NamedPipeClientStream(".", pipeName)) { channel.Connect(); Thread disconnectMonitorThread = new Thread(new ThreadStart( delegate() { TimeoutThread(channel); if (log != null) { log.WriteLine("TimeoutThread terminated - connection broken, exiting"); log.Flush(); } })); disconnectMonitorThread.Start(); while (true) { if (log != null) { log.WriteLine("Waiting"); log.Flush(); } ClientServerCommunication.Commands command; object[] args; ClientServerCommunication.ReceiveMessage(log, channel, out command, out args); object[] extraResults = null; if (log != null) { log.WriteLine("Processing command"); log.Flush(); } Profile profile; try { profile = new Profile("ImageServer process command"); if (log != null) { log.WriteLine("Command: {0}", command); log.Flush(); } switch (command) { default: Debug.Assert(false); throw new ArgumentException(command.ToString()); case ClientServerCommunication.Commands.Quit: if (args.Length != 0) { const string Message = "remote command: wrong number of arguments"; Debug.Assert(false, Message); throw new ArgumentException(Message); } if (log != null) { log.WriteLine("Main thread exiting"); log.Flush(); log.Close(); log = null; } return(0); case ClientServerCommunication.Commands.Clear: if (args.Length != 0) { const string Message = "remote command: wrong number of arguments"; Debug.Assert(false, Message); throw new ArgumentException(Message); } if (currentBitmap == null) { const string Message = "Current bitmap is null"; Debug.Assert(false, Message); throw new InvalidOperationException(Message); } currentBitmap.Dispose(); currentBitmap = null; break; case ClientServerCommunication.Commands.LoadAndOrientGDI: if (args.Length != 3) { const string Message = "remote command: wrong number of arguments"; Debug.Assert(false, Message); throw new ArgumentException(Message); } if (currentBitmap != null) { const string Message = "Current bitmap hasn't been cleared"; Debug.Assert(false, Message); throw new InvalidOperationException(Message); } Thread.CurrentThread.Priority = (ThreadPriority)args[0]; RotateFlipType exifOrientation; LoadAndOrientGDI( profile, (string)args[1], (int)args[2], out currentBitmap, out exifOrientation); extraResults = new object[] { (int)exifOrientation }; break; case ClientServerCommunication.Commands.ResizeGDI: if (args.Length != 6) { const string Message = "remote command: wrong number of arguments"; Debug.Assert(false, Message); throw new ArgumentException(Message); } if (currentBitmap != null) { const string Message = "Current bitmap hasn't been cleared"; Debug.Assert(false, Message); throw new InvalidOperationException(Message); } Thread.CurrentThread.Priority = (ThreadPriority)args[0]; ResizeGDI( profile, (string)args[1], (int)args[2], (int)args[3], (int)args[4], (int)args[5], out currentBitmap); break; case ClientServerCommunication.Commands.CreateTileGDI: if (args.Length != 10) { const string Message = "remote command: wrong number of arguments"; Debug.Assert(false, Message); throw new ArgumentException(Message); } if (currentBitmap != null) { const string Message = "Current bitmap hasn't been cleared"; Debug.Assert(false, Message); throw new InvalidOperationException(Message); } Thread.CurrentThread.Priority = (ThreadPriority)args[0]; CreateTileGDI( profile, (string)args[1], (int)args[2], (int)args[3], (int)args[4], (int)args[5], (int)args[6], (int)args[7], (int)args[8], (int)args[9], out currentBitmap); break; case ClientServerCommunication.Commands.ShrinkExpandGDI: if (args.Length != 6) { const string Message = "remote command: wrong number of arguments"; Debug.Assert(false, Message); throw new ArgumentException(Message); } Thread.CurrentThread.Priority = (ThreadPriority)args[0]; ShrinkExpandGDI( profile, (int)args[1], (int)args[2], (string)args[3], (string)args[4], (double)args[5]); break; case ClientServerCommunication.Commands.ShrinkExpandWPF: if (args.Length != 6) { const string Message = "remote command: wrong number of arguments"; Debug.Assert(false, Message); throw new ArgumentException(Message); } Thread.CurrentThread.Priority = (ThreadPriority)args[0]; ShrinkExpandWPF( profile, (int)args[1], (int)args[2], (string)args[3], (string)args[4], (double)args[5]); break; } profile.End(); } catch (Exception exception) { if (log != null) { log.WriteLine("Recoverable exception: {0}", exception); log.Flush(); } ClientServerCommunication.SendMessage( log, channel, ClientServerCommunication.Commands.Exception, new object[] { exception.ToString() }); if (log != null) { log.WriteLine("Exception response sent"); log.Flush(); } continue; } finally { Thread.CurrentThread.Priority = savedThreadPriority; } if (log != null) { log.WriteLine("Forming response"); log.Flush(); } using (MemoryStream serializedProfileStream = new MemoryStream()) { if (log != null) { log.WriteLine("Serializing profile"); log.Flush(); } new BinaryFormatter().Serialize(serializedProfileStream, profile); if (currentBitmap == null) { if (log != null) { log.WriteLine("Sending 'Done'"); log.Flush(); } ClientServerCommunication.SendMessage( log, channel, ClientServerCommunication.Commands.Done, new object[] { serializedProfileStream.ToArray() }); } else { if (log != null) { log.WriteLine("Sending 'Pending'"); log.Flush(); } ClientServerCommunication.SendMessage( log, channel, ClientServerCommunication.Commands.Pending, new object[] { (string)currentBitmap.BackingName, (int)currentBitmap.Width, (int)currentBitmap.Height, (byte[])serializedProfileStream.ToArray() }, extraResults); } } if (log != null) { log.WriteLine("Sent"); log.Flush(); } } } } catch (Exception exception) { if (log != null) { log.WriteLine("Unrecoverable exception: {0}", exception); log.Flush(); } if (currentBitmap != null) { currentBitmap.Dispose(); } if (!(exception is ClientServerCommunication.ChannelDisconnectedException)) { MessageBox.Show(exception.ToString()); } if (log != null) { log.WriteLine("Terminating abnormally"); log.Flush(); log.Close(); log = null; } return(1); } #pragma warning disable CS0162 // unreachable if (log != null) { log.WriteLine("Terminating normally"); log.Flush(); log.Close(); log = null; } #pragma warning restore CS0162 if (currentBitmap != null) { currentBitmap.Dispose(); } return(0); }