SynchronizeInvoker => Dinah.Core.Threading.SynchronizeInvoker
This commit is contained in:
parent
de93047192
commit
215a626c92
@ -1,122 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Threading;
|
|
||||||
|
|
||||||
namespace LibationWinForms
|
|
||||||
{
|
|
||||||
public class SynchronizeInvoker : ISynchronizeInvoke
|
|
||||||
{
|
|
||||||
public bool InvokeRequired => Thread.CurrentThread.ManagedThreadId != InstanceThreadId;
|
|
||||||
private int InstanceThreadId { get; set; } = Thread.CurrentThread.ManagedThreadId;
|
|
||||||
private SynchronizationContext SyncContext { get; } = SynchronizationContext.Current;
|
|
||||||
|
|
||||||
public SynchronizeInvoker()
|
|
||||||
{
|
|
||||||
if (SyncContext is null)
|
|
||||||
throw new NullReferenceException($"Could not capture a current {nameof(SynchronizationContext)}");
|
|
||||||
}
|
|
||||||
|
|
||||||
public IAsyncResult BeginInvoke(Action action) => BeginInvoke(action, null);
|
|
||||||
public IAsyncResult BeginInvoke(Delegate method) => BeginInvoke(method, null);
|
|
||||||
public IAsyncResult BeginInvoke(Delegate method, object[] args)
|
|
||||||
{
|
|
||||||
var tme = new ThreadMethodEntry(method, args);
|
|
||||||
|
|
||||||
if (InvokeRequired)
|
|
||||||
{
|
|
||||||
SyncContext.Post(OnSendOrPostCallback, tme);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tme.Complete();
|
|
||||||
tme.CompletedSynchronously = true;
|
|
||||||
}
|
|
||||||
return tme;
|
|
||||||
}
|
|
||||||
|
|
||||||
public object EndInvoke(IAsyncResult result)
|
|
||||||
{
|
|
||||||
if (result is not ThreadMethodEntry crossThread)
|
|
||||||
throw new ArgumentException($"{nameof(result)} was not returned by {nameof(SynchronizeInvoker)}.{nameof(BeginInvoke)}");
|
|
||||||
|
|
||||||
if (!crossThread.IsCompleted)
|
|
||||||
crossThread.AsyncWaitHandle.WaitOne();
|
|
||||||
|
|
||||||
return crossThread.ReturnValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public object Invoke(Action action) => Invoke(action, null);
|
|
||||||
public object Invoke(Delegate method) => Invoke(method, null);
|
|
||||||
public object Invoke(Delegate method, object[] args)
|
|
||||||
{
|
|
||||||
var tme = new ThreadMethodEntry(method, args);
|
|
||||||
|
|
||||||
if (InvokeRequired)
|
|
||||||
{
|
|
||||||
SyncContext.Send(OnSendOrPostCallback, tme);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tme.Complete();
|
|
||||||
tme.CompletedSynchronously = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return tme.ReturnValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This callback executes on the SynchronizationContext thread.
|
|
||||||
/// </summary>
|
|
||||||
private static void OnSendOrPostCallback(object asyncArgs)
|
|
||||||
{
|
|
||||||
var e = asyncArgs as ThreadMethodEntry;
|
|
||||||
e.Complete();
|
|
||||||
}
|
|
||||||
|
|
||||||
private class ThreadMethodEntry : IAsyncResult
|
|
||||||
{
|
|
||||||
public object AsyncState => null;
|
|
||||||
public bool CompletedSynchronously { get; internal set; }
|
|
||||||
public bool IsCompleted { get; private set; }
|
|
||||||
public object ReturnValue { get; private set; }
|
|
||||||
public WaitHandle AsyncWaitHandle => completedEvent;
|
|
||||||
|
|
||||||
private Delegate method;
|
|
||||||
private object[] args;
|
|
||||||
private ManualResetEvent completedEvent;
|
|
||||||
|
|
||||||
public ThreadMethodEntry(Delegate method, object[] args)
|
|
||||||
{
|
|
||||||
this.method = method;
|
|
||||||
this.args = args;
|
|
||||||
completedEvent = new ManualResetEvent(initialState: false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Complete()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
switch (method)
|
|
||||||
{
|
|
||||||
case Action actiton:
|
|
||||||
actiton();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ReturnValue = method.DynamicInvoke(args);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
IsCompleted = true;
|
|
||||||
completedEvent.Set();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
~ThreadMethodEntry()
|
|
||||||
{
|
|
||||||
completedEvent.Close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user