Improve disposal of resources
Backends can now opt-in to automatic disposal of resources in the UI thread.
This commit is contained in:
Родитель
6842df4ec2
Коммит
3cf1b0031e
|
@ -36,7 +36,7 @@ namespace Xwt.CairoBackend
|
|||
return new Cairo.LinearGradient (x0, y0, x1, y1);
|
||||
}
|
||||
|
||||
public override void DisposeLinear (object backend)
|
||||
public override void Dispose (object backend)
|
||||
{
|
||||
((IDisposable)backend).Dispose ();
|
||||
}
|
||||
|
@ -46,11 +46,6 @@ namespace Xwt.CairoBackend
|
|||
return new Cairo.RadialGradient (cx0, cy0, radius0, cx1, cy1, radius1);
|
||||
}
|
||||
|
||||
public override void DisposeRadial (object backend)
|
||||
{
|
||||
((IDisposable)backend).Dispose ();
|
||||
}
|
||||
|
||||
public override void AddColorStop (object backend, double position, Xwt.Drawing.Color color)
|
||||
{
|
||||
Cairo.Gradient g = (Cairo.Gradient) backend;
|
||||
|
|
|
@ -201,7 +201,7 @@ namespace Xwt.GtkBackend
|
|||
return new Point (pos.X, pos.Y);
|
||||
}
|
||||
|
||||
public override void DisposeBackend (object backend)
|
||||
public override void Dispose (object backend)
|
||||
{
|
||||
var tl = (IDisposable) backend;
|
||||
tl.Dispose ();
|
||||
|
|
|
@ -44,7 +44,7 @@ namespace Xwt.Mac
|
|||
};
|
||||
}
|
||||
|
||||
public override void DisposeLinear (object backend)
|
||||
public override void Dispose (object backend)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -59,10 +59,6 @@ namespace Xwt.Mac
|
|||
};
|
||||
}
|
||||
|
||||
public override void DisposeRadial (object backend)
|
||||
{
|
||||
}
|
||||
|
||||
public override void AddColorStop (object backend, double position, Xwt.Drawing.Color color)
|
||||
{
|
||||
GradientInfo gr = (GradientInfo) backend;
|
||||
|
|
|
@ -205,7 +205,7 @@ namespace Xwt.Mac
|
|||
return new Point (0,0);
|
||||
}
|
||||
|
||||
public override void DisposeBackend (object backend)
|
||||
public override void Dispose (object backend)
|
||||
{
|
||||
// nothing
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ namespace Xwt.WPFBackend
|
|||
};
|
||||
}
|
||||
|
||||
public override void DisposeLinear (object backend)
|
||||
public override void Dispose (object backend)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -62,10 +62,6 @@ namespace Xwt.WPFBackend
|
|||
};
|
||||
}
|
||||
|
||||
public override void DisposeRadial (object backend)
|
||||
{
|
||||
}
|
||||
|
||||
public override void AddColorStop (object backend, double position, Color color)
|
||||
{
|
||||
((GradientBrush)backend).GradientStops.Add (new GradientStop (color.ToWpfColor (), position));
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
//
|
||||
// ResourceBackendHandler.cs
|
||||
//
|
||||
// Author:
|
||||
// Lluis Sanchez <lluis@xamarin.com>
|
||||
//
|
||||
// Copyright (c) 2013 Xamarin Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
using System;
|
||||
|
||||
namespace Xwt.Backends
|
||||
{
|
||||
public class DisposableResourceBackendHandler: BackendHandler
|
||||
{
|
||||
public virtual bool DisposeHandleOnUiThread {
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public virtual void Dispose (object backend)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -29,7 +29,7 @@ using Xwt.Drawing;
|
|||
|
||||
namespace Xwt.Backends
|
||||
{
|
||||
public abstract class DrawingPathBackendHandler: BackendHandler
|
||||
public abstract class DrawingPathBackendHandler: DisposableResourceBackendHandler
|
||||
{
|
||||
public abstract void Arc (object backend, double xc, double yc, double radius, double angle1, double angle2);
|
||||
|
||||
|
@ -58,8 +58,6 @@ namespace Xwt.Backends
|
|||
public abstract void AppendPath (object backend, object otherBackend);
|
||||
|
||||
public abstract bool IsPointInFill (object backend, double x, double y);
|
||||
|
||||
public abstract void Dispose (object backend);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,12 +29,10 @@ using Xwt.Drawing;
|
|||
|
||||
namespace Xwt.Backends
|
||||
{
|
||||
public abstract class GradientBackendHandler: BackendHandler
|
||||
public abstract class GradientBackendHandler: DisposableResourceBackendHandler
|
||||
{
|
||||
public abstract object CreateLinear (double x0, double y0, double x1, double y1);
|
||||
public abstract void DisposeLinear (object backend);
|
||||
public abstract object CreateRadial (double cx0, double cy0, double radius0, double cx1, double cy1, double radius1);
|
||||
public abstract void DisposeRadial (object backend);
|
||||
public abstract void AddColorStop (object backend, double position, Color color);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,17 +32,13 @@ using System.Collections.Generic;
|
|||
|
||||
namespace Xwt.Backends
|
||||
{
|
||||
public abstract class ImageBackendHandler: BackendHandler
|
||||
public abstract class ImageBackendHandler: DisposableResourceBackendHandler
|
||||
{
|
||||
public virtual object CreateBackend ()
|
||||
{
|
||||
throw new NotSupportedException ();
|
||||
}
|
||||
|
||||
public virtual void Dispose (object backend)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual object LoadFromResource (Assembly asm, string name)
|
||||
{
|
||||
using (var s = asm.GetManifestResourceStream (name)) {
|
||||
|
|
|
@ -28,12 +28,11 @@ using Xwt.Drawing;
|
|||
|
||||
namespace Xwt.Backends
|
||||
{
|
||||
public abstract class ImageBuilderBackendHandler: BackendHandler
|
||||
public abstract class ImageBuilderBackendHandler: DisposableResourceBackendHandler
|
||||
{
|
||||
public abstract object CreateImageBuilder (int width, int height, ImageFormat format);
|
||||
public abstract object CreateContext (object backend);
|
||||
public abstract object CreateImage (object backend);
|
||||
public abstract void Dispose (object backend);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,10 +27,9 @@ using System;
|
|||
|
||||
namespace Xwt.Backends
|
||||
{
|
||||
public abstract class ImagePatternBackendHandler: BackendHandler
|
||||
public abstract class ImagePatternBackendHandler: DisposableResourceBackendHandler
|
||||
{
|
||||
public abstract object Create (ImageDescription img);
|
||||
public abstract void Dispose (object backend);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
//
|
||||
// ResourceManager.cs
|
||||
//
|
||||
// Author:
|
||||
// Lluis Sanchez <lluis@xamarin.com>
|
||||
//
|
||||
// Copyright (c) 2013 Xamarin Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Xwt.Backends
|
||||
{
|
||||
static class ResourceManager
|
||||
{
|
||||
static bool finalized;
|
||||
static Dictionary<object,Action<object>> resources = new Dictionary<object,Action<object>> ();
|
||||
static Dictionary<object,Action<object>> freedResources = new Dictionary<object,Action<object>> ();
|
||||
|
||||
public static void RegisterResource (object res, Action<object> disposeCallback = null)
|
||||
{
|
||||
if (finalized)
|
||||
return;
|
||||
lock (resources)
|
||||
resources [res] = disposeCallback;
|
||||
}
|
||||
|
||||
public static bool FreeResource (object res)
|
||||
{
|
||||
if (finalized || res == null)
|
||||
return true;
|
||||
|
||||
lock (resources) {
|
||||
Action<object> disposer;
|
||||
if (!resources.TryGetValue (res, out disposer))
|
||||
return false;
|
||||
|
||||
resources.Remove (res);
|
||||
|
||||
if (System.Threading.Thread.CurrentThread == Application.UIThread) {
|
||||
DisposeResource (res, disposer);
|
||||
} else {
|
||||
lock (freedResources) {
|
||||
if (freedResources.Count == 0)
|
||||
Application.Invoke (DisposeResources);
|
||||
freedResources [res] = disposer;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static void DisposeResource (object res, Action<object> disposer)
|
||||
{
|
||||
try {
|
||||
if (disposer != null)
|
||||
disposer (res);
|
||||
else if (res is IDisposable)
|
||||
((IDisposable)res).Dispose ();
|
||||
} catch (Exception ex) {
|
||||
Application.NotifyException (ex);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void DisposeResources ()
|
||||
{
|
||||
lock (freedResources) {
|
||||
if (finalized)
|
||||
return;
|
||||
foreach (var r in freedResources) {
|
||||
DisposeResource (r.Key, r.Value);
|
||||
}
|
||||
freedResources.Clear ();
|
||||
}
|
||||
}
|
||||
|
||||
internal static void Dispose ()
|
||||
{
|
||||
lock (freedResources) {
|
||||
DisposeResources ();
|
||||
finalized = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -31,7 +31,7 @@ using System.Collections.Generic;
|
|||
|
||||
namespace Xwt.Backends
|
||||
{
|
||||
public abstract class TextLayoutBackendHandler: BackendHandler
|
||||
public abstract class TextLayoutBackendHandler: DisposableResourceBackendHandler
|
||||
{
|
||||
public abstract object Create ();
|
||||
|
||||
|
@ -43,7 +43,6 @@ namespace Xwt.Backends
|
|||
public abstract Size GetSize (object backend);
|
||||
public abstract int GetIndexFromCoordinates (object backend, double x, double y);
|
||||
public abstract Point GetCoordinateFromIndex (object backend, int index);
|
||||
public abstract void DisposeBackend (object backend);
|
||||
|
||||
public abstract void AddAttribute (object backend, TextAttribute attribute);
|
||||
public abstract void ClearAttributes (object backend);
|
||||
|
|
|
@ -36,11 +36,36 @@ namespace Xwt.Drawing
|
|||
{
|
||||
handler = Toolkit.CurrentEngine.VectorImageRecorderContextHandler;
|
||||
Backend = handler.CreatePath ();
|
||||
Init ();
|
||||
}
|
||||
|
||||
internal DrawingPath (object backend, Toolkit toolkit, DrawingPathBackendHandler h): base (backend, toolkit)
|
||||
{
|
||||
handler = h;
|
||||
Init ();
|
||||
}
|
||||
|
||||
void Init ()
|
||||
{
|
||||
if (handler.DisposeHandleOnUiThread)
|
||||
ResourceManager.RegisterResource (Backend, handler.Dispose);
|
||||
else
|
||||
GC.SuppressFinalize (this);
|
||||
}
|
||||
|
||||
public void Dispose ()
|
||||
{
|
||||
if (handler.DisposeHandleOnUiThread) {
|
||||
GC.SuppressFinalize (this);
|
||||
ResourceManager.FreeResource (Backend);
|
||||
}
|
||||
else
|
||||
handler.Dispose (Backend);
|
||||
}
|
||||
|
||||
~DrawingPath ()
|
||||
{
|
||||
ResourceManager.FreeResource (Backend);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -318,11 +343,6 @@ namespace Xwt.Drawing
|
|||
{
|
||||
return handler.IsPointInFill (Backend, x, y);
|
||||
}
|
||||
|
||||
public void Dispose ()
|
||||
{
|
||||
handler.Dispose (Backend);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -488,6 +488,9 @@ namespace Xwt.Drawing
|
|||
{
|
||||
this.backend = backend;
|
||||
this.toolkit = toolkit;
|
||||
|
||||
if (toolkit.ImageBackendHandler.DisposeHandleOnUiThread)
|
||||
ResourceManager.RegisterResource (backend, toolkit.ImageBackendHandler.Dispose);
|
||||
}
|
||||
|
||||
public void AddReference ()
|
||||
|
@ -497,8 +500,15 @@ namespace Xwt.Drawing
|
|||
|
||||
public void ReleaseReference (bool disposing)
|
||||
{
|
||||
if (System.Threading.Interlocked.Decrement (ref referenceCount) == 0 && disposing)
|
||||
toolkit.ImageBackendHandler.Dispose (backend);
|
||||
if (System.Threading.Interlocked.Decrement (ref referenceCount) == 0) {
|
||||
if (disposing) {
|
||||
if (toolkit.ImageBackendHandler.DisposeHandleOnUiThread)
|
||||
ResourceManager.FreeResource (backend);
|
||||
else
|
||||
toolkit.ImageBackendHandler.Dispose (backend);
|
||||
} else
|
||||
ResourceManager.FreeResource (backend);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,14 +33,8 @@ namespace Xwt.Drawing
|
|||
{
|
||||
public ImagePattern (Image image)
|
||||
{
|
||||
Backend = ToolkitEngine.ImagePatternBackendHandler.Create (image != null ? image.ImageDescription : ImageDescription.Null);
|
||||
SetBackend (ToolkitEngine.ImagePatternBackendHandler, ToolkitEngine.ImagePatternBackendHandler.Create (image != null ? image.ImageDescription : ImageDescription.Null));
|
||||
}
|
||||
|
||||
public override void Dispose ()
|
||||
{
|
||||
ToolkitEngine.ImagePatternBackendHandler.Dispose (Backend);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,12 +33,7 @@ namespace Xwt.Drawing
|
|||
{
|
||||
public LinearGradient (double xStart, double yStart, double xEnd, double yEnd)
|
||||
{
|
||||
Backend = ToolkitEngine.GradientBackendHandler.CreateLinear (xStart, yStart, xEnd, yEnd);
|
||||
}
|
||||
|
||||
public override void Dispose ()
|
||||
{
|
||||
ToolkitEngine.GradientBackendHandler.DisposeLinear (Backend);
|
||||
SetBackend (ToolkitEngine.GradientBackendHandler, ToolkitEngine.GradientBackendHandler.CreateLinear (xStart, yStart, xEnd, yEnd));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,16 +25,41 @@
|
|||
// THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using Xwt.Backends;
|
||||
|
||||
namespace Xwt.Drawing
|
||||
{
|
||||
public abstract class Pattern: XwtObject, IDisposable
|
||||
{
|
||||
DisposableResourceBackendHandler handler;
|
||||
|
||||
internal Pattern ()
|
||||
{
|
||||
}
|
||||
|
||||
public abstract void Dispose ();
|
||||
internal void SetBackend (DisposableResourceBackendHandler handler, object backend)
|
||||
{
|
||||
Backend = backend;
|
||||
this.handler = handler;
|
||||
if (handler.DisposeHandleOnUiThread)
|
||||
ResourceManager.RegisterResource (backend, handler.Dispose);
|
||||
else
|
||||
GC.SuppressFinalize (this);
|
||||
}
|
||||
|
||||
~Pattern ()
|
||||
{
|
||||
ResourceManager.FreeResource (Backend);
|
||||
}
|
||||
|
||||
public void Dispose ()
|
||||
{
|
||||
if (handler.DisposeHandleOnUiThread) {
|
||||
GC.SuppressFinalize (this);
|
||||
ResourceManager.FreeResource (Backend);
|
||||
} else
|
||||
handler.Dispose (Backend);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,12 +33,7 @@ namespace Xwt.Drawing
|
|||
{
|
||||
public RadialGradient (double cx0, double cy0, double radius0, double cx1, double cy1, double radius1)
|
||||
{
|
||||
Backend = ToolkitEngine.GradientBackendHandler.CreateRadial (cx0, cy0, radius0, cx1, cy1, radius1);
|
||||
}
|
||||
|
||||
public override void Dispose ()
|
||||
{
|
||||
ToolkitEngine.GradientBackendHandler.DisposeRadial (Backend);
|
||||
SetBackend (ToolkitEngine.GradientBackendHandler, ToolkitEngine.GradientBackendHandler.CreateRadial (cx0, cy0, radius0, cx1, cy1, radius1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@ namespace Xwt.Drawing
|
|||
handler = ToolkitEngine.TextLayoutBackendHandler;
|
||||
Backend = handler.Create ();
|
||||
Font = Font.SystemFont;
|
||||
Setup ();
|
||||
}
|
||||
|
||||
public TextLayout (Canvas canvas)
|
||||
|
@ -56,6 +57,7 @@ namespace Xwt.Drawing
|
|||
handler = ToolkitEngine.TextLayoutBackendHandler;
|
||||
Backend = handler.Create ();
|
||||
Font = canvas.Font;
|
||||
Setup ();
|
||||
}
|
||||
|
||||
internal TextLayout (Toolkit tk)
|
||||
|
@ -63,6 +65,29 @@ namespace Xwt.Drawing
|
|||
ToolkitEngine = tk;
|
||||
handler = ToolkitEngine.TextLayoutBackendHandler;
|
||||
Backend = handler.Create ();
|
||||
Setup ();
|
||||
}
|
||||
|
||||
void Setup ()
|
||||
{
|
||||
if (handler.DisposeHandleOnUiThread)
|
||||
ResourceManager.RegisterResource (Backend, handler.Dispose);
|
||||
else
|
||||
GC.SuppressFinalize (this);
|
||||
}
|
||||
|
||||
public void Dispose ()
|
||||
{
|
||||
if (handler.DisposeHandleOnUiThread) {
|
||||
GC.SuppressFinalize (this);
|
||||
ResourceManager.FreeResource (Backend);
|
||||
} else
|
||||
handler.Dispose (Backend);
|
||||
}
|
||||
|
||||
~TextLayout ()
|
||||
{
|
||||
ResourceManager.FreeResource (Backend);
|
||||
}
|
||||
|
||||
internal TextLayoutData GetData ()
|
||||
|
@ -255,11 +280,6 @@ namespace Xwt.Drawing
|
|||
{
|
||||
AddAttribute (new StrikethroughTextAttribute () { StartIndex = startIndex, Count = count});
|
||||
}
|
||||
|
||||
public void Dispose ()
|
||||
{
|
||||
handler.DisposeBackend (Backend);
|
||||
}
|
||||
}
|
||||
|
||||
public enum TextTrimming {
|
||||
|
|
|
@ -116,14 +116,31 @@ namespace Xwt.Drawing
|
|||
public override object CreateNativeBackend ()
|
||||
{
|
||||
imageBuilder = toolkit.ImageBuilderBackendHandler.CreateImageBuilder ((int)width, (int)height, ImageFormat.ARGB32);
|
||||
if (toolkit.ImageBuilderBackendHandler.DisposeHandleOnUiThread)
|
||||
ResourceManager.RegisterResource (imageBuilder);
|
||||
else
|
||||
GC.SuppressFinalize (this);
|
||||
|
||||
return toolkit.ImageBuilderBackendHandler.CreateContext (imageBuilder);
|
||||
}
|
||||
|
||||
~VectorContextBackend ()
|
||||
{
|
||||
if (imageBuilder != null)
|
||||
ResourceManager.FreeResource (imageBuilder);
|
||||
}
|
||||
|
||||
public override void Dispose ()
|
||||
{
|
||||
base.Dispose ();
|
||||
if (imageBuilder != null)
|
||||
toolkit.ImageBuilderBackendHandler.Dispose (imageBuilder);
|
||||
if (imageBuilder != null) {
|
||||
if (toolkit.ImageBuilderBackendHandler.DisposeHandleOnUiThread) {
|
||||
GC.SuppressFinalize (this);
|
||||
ResourceManager.FreeResource (imageBuilder);
|
||||
}
|
||||
else
|
||||
toolkit.ImageBuilderBackendHandler.Dispose (imageBuilder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -414,6 +414,8 @@
|
|||
<Compile Include="Xwt\TableCalc.cs" />
|
||||
<Compile Include="Xwt\VSlider.cs" />
|
||||
<Compile Include="Xwt\HSlider.cs" />
|
||||
<Compile Include="Xwt.Backends\ResourceManager.cs" />
|
||||
<Compile Include="Xwt.Backends\DisposableResourceBackendHandler.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<ItemGroup />
|
||||
|
|
|
@ -102,7 +102,18 @@ namespace Xwt
|
|||
engine.ExitApplication ();
|
||||
});
|
||||
}
|
||||
/// <summary>
|
||||
|
||||
/// <summary>
|
||||
/// Releases all resource used by the application
|
||||
/// </summary>
|
||||
/// <remarks>This method must be called before the application process ends</remarks>
|
||||
public static void Dispose ()
|
||||
{
|
||||
ResourceManager.Dispose ();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Invokes an action in the GUI thread
|
||||
/// </summary>
|
||||
/// <param name='action'>
|
||||
|
|
Загрузка…
Ссылка в новой задаче