mirror of
https://github.com/qmlnet/qmlnet.git
synced 2026-05-21 06:45:32 -06:00
Ensuring UI thread. Making it optional.
This commit is contained in:
parent
53d6189d11
commit
178648fc27
7 changed files with 60 additions and 28 deletions
|
|
@ -9,6 +9,7 @@ namespace Qml.Net.Tests
|
|||
|
||||
protected BaseTests()
|
||||
{
|
||||
QmlNetConfig.ShouldEnsureUIThread = false; // Not need for unit tests.
|
||||
Monitor.Enter(LockObject);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -245,12 +245,12 @@ namespace Qml.Net.Internal
|
|||
}
|
||||
|
||||
var result = componentCompelted.ComponentCompleted();
|
||||
if (Tasks.ListenForExceptionsWhenInvokingTasks)
|
||||
if (QmlNetConfig.ListenForExceptionsWhenInvokingTasks)
|
||||
{
|
||||
result?.ContinueWith(
|
||||
task =>
|
||||
{
|
||||
Tasks.RaiseUnhandledTaskException(task.Exception);
|
||||
QmlNetConfig.RaiseUnhandledTaskException(task.Exception);
|
||||
},
|
||||
TaskContinuationOptions.OnlyOnFaulted);
|
||||
}
|
||||
|
|
@ -344,12 +344,12 @@ namespace Qml.Net.Internal
|
|||
Task resultTask = null;
|
||||
del(target, parameters, result, ref resultTask);
|
||||
|
||||
if (Tasks.ListenForExceptionsWhenInvokingTasks)
|
||||
if (QmlNetConfig.ListenForExceptionsWhenInvokingTasks)
|
||||
{
|
||||
resultTask?.ContinueWith(
|
||||
task =>
|
||||
{
|
||||
Tasks.RaiseUnhandledTaskException(task.Exception);
|
||||
QmlNetConfig.RaiseUnhandledTaskException(task.Exception);
|
||||
},
|
||||
TaskContinuationOptions.OnlyOnFaulted);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ namespace Qml.Net.Internal.Types
|
|||
{
|
||||
return obj;
|
||||
}
|
||||
|
||||
throw new InvalidOperationException($"No object found for object id {ObjectId}");
|
||||
}
|
||||
}
|
||||
|
|
@ -33,6 +34,8 @@ namespace Qml.Net.Internal.Types
|
|||
|
||||
public bool ActivateSignal(string signalName, params object[] parameters)
|
||||
{
|
||||
QmlNetConfig.EnsureUIThread();
|
||||
|
||||
if (parameters != null && parameters.Length > 0)
|
||||
{
|
||||
using (var list = new NetVariantList())
|
||||
|
|
@ -45,6 +48,7 @@ namespace Qml.Net.Internal.Types
|
|||
list.Add(variant);
|
||||
}
|
||||
}
|
||||
|
||||
return Interop.NetReference.ActivateSignal(Handle, signalName, list.Handle) == 1;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ namespace Qml.Net
|
|||
private GCHandle _triggerHandle;
|
||||
private GCHandle _aboutToQuitHandle;
|
||||
private readonly List<AboutToQuitEventHandler> _aboutToQuitEventHandlers = new List<AboutToQuitEventHandler>();
|
||||
private static int _threadId;
|
||||
private static int? _threadId;
|
||||
|
||||
protected QCoreApplication(IntPtr handle, bool ownsHandle)
|
||||
: base(handle, ownsHandle)
|
||||
|
|
@ -66,7 +66,18 @@ namespace Qml.Net
|
|||
SynchronizationContext.SetSynchronizationContext(new QtSynchronizationContext(this));
|
||||
}
|
||||
|
||||
public static bool IsMainThread => Environment.CurrentManagedThreadId == _threadId;
|
||||
public static bool IsMainThread
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!_threadId.HasValue)
|
||||
{
|
||||
throw new Exception("QCoreApplication hasn't been created yet, can't determine what thread is the main thread.");
|
||||
}
|
||||
|
||||
return Environment.CurrentManagedThreadId == _threadId;
|
||||
}
|
||||
}
|
||||
|
||||
public int Exec()
|
||||
{
|
||||
|
|
|
|||
38
src/net/Qml.Net/QmlNetConfig.cs
Normal file
38
src/net/Qml.Net/QmlNetConfig.cs
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
using System;
|
||||
|
||||
namespace Qml.Net
|
||||
{
|
||||
public class QmlNetConfig
|
||||
{
|
||||
public static bool ListenForExceptionsWhenInvokingTasks { get; set; }
|
||||
|
||||
public static event Action<AggregateException> UnhandledTaskException;
|
||||
|
||||
internal static void RaiseUnhandledTaskException(AggregateException ex)
|
||||
{
|
||||
var handler = UnhandledTaskException;
|
||||
handler?.Invoke(ex);
|
||||
}
|
||||
|
||||
public static bool ShouldEnsureUIThread { get; set; } = true;
|
||||
|
||||
public static Action EnsureUIThreadDelegate = () =>
|
||||
{
|
||||
if (QCoreApplication.IsMainThread)
|
||||
{
|
||||
throw new Exception(
|
||||
"You must be on the UI thread to perform this task. See https://github.com/qmlnet/qmlnet/issues/112");
|
||||
}
|
||||
};
|
||||
|
||||
internal static void EnsureUIThread()
|
||||
{
|
||||
if (!ShouldEnsureUIThread)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
EnsureUIThreadDelegate?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -13,11 +13,6 @@ namespace Qml.Net
|
|||
{
|
||||
public static bool ActivateSignal(this object instance, string signalName, params object[] args)
|
||||
{
|
||||
if (!QCoreApplication.IsMainThread)
|
||||
{
|
||||
throw new Exception("An attempt was made to activate a signal from a non-UI thread.");
|
||||
}
|
||||
|
||||
var existing = NetReference.CreateForObject(instance, false /*Ignore if not tagged*/);
|
||||
if (existing != null && existing.ActivateSignal(signalName, args))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,17 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace Qml.Net
|
||||
{
|
||||
public static class Tasks
|
||||
{
|
||||
public static bool ListenForExceptionsWhenInvokingTasks { get; set; }
|
||||
|
||||
public static event Action<AggregateException> UnhandledTaskException;
|
||||
|
||||
internal static void RaiseUnhandledTaskException(AggregateException ex)
|
||||
{
|
||||
var handler = UnhandledTaskException;
|
||||
handler?.Invoke(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue