From 2bbee634d09ea6944bf7c3f941e5435850a4bd57 Mon Sep 17 00:00:00 2001 From: Bertrand Lorentz Date: Thu, 8 Nov 2012 22:27:38 +0100 Subject: [PATCH] sample: Add AsyncSample to showcase GLibSynchronizationContext Add a sample to illustrate the point of having a GLibSynchronizationContext, but with the async/await code ifdef'ed out because we don't require Mono 3.0 for now. Instead, provide a crude equivalent of what would be generated by the compiler, to show that it works. --- sample/AsyncSample.cs | 109 ++++++++++++++++++++++++++++++++++++++++++ sample/Makefile.am | 6 ++- sample/sample.csproj | 1 + 3 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 sample/AsyncSample.cs diff --git a/sample/AsyncSample.cs b/sample/AsyncSample.cs new file mode 100644 index 000000000..6d412b4ba --- /dev/null +++ b/sample/AsyncSample.cs @@ -0,0 +1,109 @@ +// AsyncSample.cs - Async call using SynchronizationContext +// +// Author: Bertrand Lorentz +// +// Copyright (c) 2012 Bertrand Lorentz +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of version 2 of the Lesser GNU General +// Public License as published by the Free Software Foundation. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this program; if not, write to the +// Free Software Foundation, Inc., 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. + +namespace Samples +{ + using Gtk; + using Gdk; + using System; + using System.Threading; + + public class AsyncSample + { + static Label msg; + static Label label; + static Button button; + static int count; + static Thread main_thread; + + public static int Main (string[] args) + { + Application.Init (); + main_thread = Thread.CurrentThread; + + Gtk.Window win = new Gtk.Window ("Gtk# Hello Async World"); + win.DeleteEvent += new DeleteEventHandler (Window_Delete); + label = new Label ("Doing nothing"); + msg = new Label ("Do Work"); + button = new Button (msg); + button.Clicked += delegate { DoWork (); }; + VBox box = new VBox (true, 8); + box.Add (label); + box.Add (button); + win.Add (box); + win.BorderWidth = 4; + win.ShowAll (); + + Application.Run (); + + return 0; + } + +#if NET_4_5 // Enable this when we require Mono 3.0 + static async void DoWork () + { + label.Text = "Starting Work"; + + int res = await DoLongOperation (); + + CheckThread ("Updating UI"); + label.Text = String.Format ("Work Done ({0})", res); + } +#else + static void DoWork () + { + label.Text = "Starting Work"; + + var sc = SynchronizationContext.Current; + ThreadPool.QueueUserWorkItem (delegate { + int res = DoLongOperation (); + sc.Post (delegate { + CheckThread ("Updating UI"); + label.Text = String.Format ("Work Done ({0})", res); + }, null); + }); + } +#endif + + static int DoLongOperation () + { + count++; + CheckThread ("Doing long operation"); + Thread.Sleep (2000); + return count; + } + + static void CheckThread (string msg) + { + if (Thread.CurrentThread == main_thread) { + Console.WriteLine ("In main thread - {0}", msg); + } else { + Console.WriteLine ("Not in main thread - {0}", msg); + } + } + + static void Window_Delete (object obj, DeleteEventArgs args) + { + Application.Quit (); + args.RetVal = true; + } + } +} + diff --git a/sample/Makefile.am b/sample/Makefile.am index dc1290548..fd48ab858 100755 --- a/sample/Makefile.am +++ b/sample/Makefile.am @@ -8,7 +8,7 @@ DOTNET_TARGETS= DOTNET_ASSEMBLY= endif -TARGETS = gtk-hello-world.exe button.exe calendar.exe subclass.exe menu.exe treeviewdemo.exe managedtreeviewdemo.exe nodeviewdemo.exe treemodeldemo.exe actions.exe spawn.exe assistant.exe registerprop.exe gexceptiontest.exe native-instantiation.exe polarfixed.exe cairo-sample.exe scribble.exe testdnd.exe custom-cellrenderer.exe custom-widget.exe custom-scrollable.exe #scribble-xinput.exe $(DOTNET_TARGETS) +TARGETS = gtk-hello-world.exe async-sample.exe button.exe calendar.exe subclass.exe menu.exe treeviewdemo.exe managedtreeviewdemo.exe nodeviewdemo.exe treemodeldemo.exe actions.exe spawn.exe assistant.exe registerprop.exe gexceptiontest.exe native-instantiation.exe polarfixed.exe cairo-sample.exe scribble.exe testdnd.exe custom-cellrenderer.exe custom-widget.exe custom-scrollable.exe #scribble-xinput.exe $(DOTNET_TARGETS) DEBUGS = $(addsuffix .mdb, $(TARGETS)) @@ -29,6 +29,9 @@ CLEANFILES = $(TARGETS) $(DEBUGS) gtk-hello-world.exe: $(srcdir)/HelloWorld.cs $(assemblies) $(CSC) $(CSFLAGS) -out:gtk-hello-world.exe $(references) $(srcdir)/HelloWorld.cs +async-sample.exe: $(srcdir)/AsyncSample.cs $(assemblies) + $(CSC) $(CSFLAGS) -out:async-sample.exe $(references) $(srcdir)/AsyncSample.cs + button.exe: $(srcdir)/ButtonApp.cs $(assemblies) $(CSC) $(CSFLAGS) -out:button.exe $(references) $(srcdir)/ButtonApp.cs @@ -103,6 +106,7 @@ gexceptiontest.exe: $(srcdir)/GExceptionTest.cs $(assemblies) EXTRA_DIST = \ HelloWorld.cs \ Assistant.cs \ + AsyncSample.cs \ ButtonApp.cs \ CalendarApp.cs \ Subclass.cs \ diff --git a/sample/sample.csproj b/sample/sample.csproj index 4e5650553..dd7948446 100644 --- a/sample/sample.csproj +++ b/sample/sample.csproj @@ -104,6 +104,7 @@ +