#develop (short for SharpDevelop) is a free IDE for .NET programming languages.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

122 lines
3.0 KiB

// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.ComponentModel;
using System.Reflection;
using System.Threading;
using System.Windows.Threading;
using ICSharpCode.SharpDevelop;
namespace ICSharpCode.SharpSnippetCompiler.Core
{
/// <summary>
/// Implements the ISynchronizeInvoke interface by using a WPF dispatcher
/// to perform the cross-thread call.
/// </summary>
sealed class WpfSynchronizeInvoke : ISynchronizeInvoke
{
readonly Dispatcher dispatcher;
public WpfSynchronizeInvoke(Dispatcher dispatcher)
{
if (dispatcher == null)
throw new ArgumentNullException("dispatcher");
this.dispatcher = dispatcher;
}
public bool InvokeRequired {
get {
return !dispatcher.CheckAccess();
}
}
public IAsyncResult BeginInvoke(Delegate method, object[] args)
{
DispatcherOperation op;
if (args == null || args.Length == 0)
op = dispatcher.BeginInvoke(DispatcherPriority.Normal, method);
else if (args.Length == 1)
op = dispatcher.BeginInvoke(DispatcherPriority.Normal, method, args[0]);
else
op = dispatcher.BeginInvoke(DispatcherPriority.Normal, method, args[0], args.Splice(1));
return new AsyncResult(op);
}
sealed class AsyncResult : IAsyncResult
{
internal readonly DispatcherOperation op;
readonly object lockObj = new object();
ManualResetEvent resetEvent;
public AsyncResult(DispatcherOperation op)
{
this.op = op;
}
public bool IsCompleted {
get {
return op.Status == DispatcherOperationStatus.Completed;
}
}
public WaitHandle AsyncWaitHandle {
get {
lock (lockObj) {
if (resetEvent == null) {
op.Completed += op_Completed;
resetEvent = new ManualResetEvent(false);
if (IsCompleted)
resetEvent.Set();
}
return resetEvent;
}
}
}
void op_Completed(object sender, EventArgs e)
{
lock (lockObj) {
resetEvent.Set();
}
}
public object AsyncState {
get { return null; }
}
public bool CompletedSynchronously {
get { return false; }
}
}
public object EndInvoke(IAsyncResult result)
{
AsyncResult r = result as AsyncResult;
if (r == null)
throw new ArgumentException("result must be the return value of a WpfSynchronizeInvoke.BeginInvoke call!");
r.op.Wait();
return r.op.Result;
}
public object Invoke(Delegate method, object[] args)
{
object result = null;
Exception exception = null;
dispatcher.Invoke(
DispatcherPriority.Normal,
(Action)delegate {
try {
result = method.DynamicInvoke(args);
} catch (TargetInvocationException ex) {
exception = ex.InnerException;
}
});
// if an exception occurred, re-throw it on the calling thread
if (exception != null)
throw new TargetInvocationException(exception);
return result;
}
}
}