Imported Upstream version 3.6.0

Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
This commit is contained in:
Jo Shields
2014-08-13 10:39:27 +01:00
commit a575963da9
50588 changed files with 8155799 additions and 0 deletions

View File

@@ -0,0 +1,29 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
#if HAS_WINRT
using Windows.Foundation;
namespace System.Reactive
{
class EventPatternSource<TSender, TEventArgs> : EventPatternSourceBase<TSender, TEventArgs>, IEventPatternSource<TSender, TEventArgs>
{
public EventPatternSource(IObservable<EventPattern<TSender, TEventArgs>> source, Action<Action<TSender, TEventArgs>, /*object,*/ EventPattern<TSender, TEventArgs>> invokeHandler)
: base(source, invokeHandler)
{
}
event TypedEventHandler<TSender, TEventArgs> IEventPatternSource<TSender, TEventArgs>.OnNext
{
add
{
Add(value, (o, e) => value(o, e));
}
remove
{
Remove(value);
}
}
}
}
#endif

View File

@@ -0,0 +1,249 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
#if HAS_WINRT
using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Reactive.Subjects;
using System.Threading;
using Windows.Foundation;
namespace System.Reactive.Windows.Foundation
{
/// <summary>
/// Provides conversions from Windows Runtime asynchronous actions and operations to observable sequences.
/// </summary>
public static class AsyncInfoObservableExtensions
{
#region IAsyncAction and IAsyncActionWithProgress
/// <summary>
/// Converts a Windows Runtime asynchronous action to an observable sequence.
/// Each observer subscribed to the resulting observable sequence will be notified about the action's successful or exceptional completion.
/// </summary>
/// <param name="source">Asynchronous action to convert.</param>
/// <returns>An observable sequence that produces a unit value when the asynchronous action completes, or propagates the exception produced by the asynchronous action.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
public static IObservable<Unit> ToObservable(this IAsyncAction source)
{
if (source == null)
throw new ArgumentNullException("source");
return new AsyncInfoToObservableBridge<Unit, Unit>(
source,
(iai, a) => ((IAsyncAction)iai).Completed += new AsyncActionCompletedHandler((iaa, status) => a(iaa, status)),
iai => Unit.Default,
onProgress: null,
progress: null,
multiValue: false
);
}
/// <summary>
/// Converts a Windows Runtime asynchronous action to an observable sequence, ignoring its progress notifications.
/// Each observer subscribed to the resulting observable sequence will be notified about the action's successful or exceptional completion.
/// </summary>
/// <typeparam name="TProgress">The type of the reported progress objects, which get ignored by this conversion.</typeparam>
/// <param name="source">Asynchronous action to convert.</param>
/// <returns>An observable sequence that produces a unit value when the asynchronous action completes, or propagates the exception produced by the asynchronous action.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
public static IObservable<Unit> ToObservable<TProgress>(this IAsyncActionWithProgress<TProgress> source)
{
if (source == null)
throw new ArgumentNullException("source");
return source.ToObservable_(null);
}
/// <summary>
/// Converts a Windows Runtime asynchronous action to an observable sequence, reporting its progress through the supplied progress object.
/// Each observer subscribed to the resulting observable sequence will be notified about the action's successful or exceptional completion.
/// </summary>
/// <typeparam name="TProgress">The type of the reported progress objects.</typeparam>
/// <param name="source">Asynchronous action to convert.</param>
/// <param name="progress">Progress object to receive progress notifications on.</param>
/// <returns>An observable sequence that produces a unit value when the asynchronous action completes, or propagates the exception produced by the asynchronous action.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="progress"/> is null.</exception>
public static IObservable<Unit> ToObservable<TProgress>(this IAsyncActionWithProgress<TProgress> source, IProgress<TProgress> progress)
{
if (source == null)
throw new ArgumentNullException("source");
if (progress == null)
throw new ArgumentNullException("progress");
return source.ToObservable_(progress);
}
/// <summary>
/// Converts a Windows Runtime asynchronous action to an observable sequence reporting its progress.
/// Each observer subscribed to the resulting observable sequence will be notified about the action's succesful or exceptional completion.
/// </summary>
/// <typeparam name="TProgress">The type of the reported progress objects.</typeparam>
/// <param name="source">Asynchronous action to convert.</param>
/// <returns>An observable sequence that produces progress values from the asynchronous action and notifies observers about the action's completion.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
public static IObservable<TProgress> ToObservableProgress<TProgress>(this IAsyncActionWithProgress<TProgress> source)
{
if (source == null)
throw new ArgumentNullException("source");
return Observable.Create<TProgress>(observer =>
{
var progress = observer.ToProgress();
var src = source.ToObservable_(progress);
return src.Subscribe(_ => { }, observer.OnError, observer.OnCompleted);
});
}
private static IObservable<Unit> ToObservable_<TProgress>(this IAsyncActionWithProgress<TProgress> source, IProgress<TProgress> progress)
{
return new AsyncInfoToObservableBridge<Unit, TProgress>(
source,
(iai, a) => ((IAsyncActionWithProgress<TProgress>)iai).Completed += new AsyncActionWithProgressCompletedHandler<TProgress>((iaa, status) => a(iaa, status)),
iai => Unit.Default,
(iai, a) => ((IAsyncActionWithProgress<TProgress>)iai).Progress += new AsyncActionProgressHandler<TProgress>((iap, p) => a(iap, p)),
progress,
multiValue: false
);
}
#endregion
#region IAsyncOperation and IAsyncOperationWithProgress
/// <summary>
/// Converts a Windows Runtime asynchronous operation to an observable sequence reporting its result.
/// Each observer subscribed to the resulting observable sequence will be notified about the operation's single result and its successful exceptional completion.
/// </summary>
/// <typeparam name="TResult">The type of the asynchronous operation's result.</typeparam>
/// <param name="source">Asynchronous operation to convert.</param>
/// <returns>An observable sequence that notifies observers about the asynchronous operation's result value and completion.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
public static IObservable<TResult> ToObservable<TResult>(this IAsyncOperation<TResult> source)
{
if (source == null)
throw new ArgumentNullException("source");
return new AsyncInfoToObservableBridge<TResult, Unit>(
source,
(iai, a) => ((IAsyncOperation<TResult>)iai).Completed += new AsyncOperationCompletedHandler<TResult>((iao, status) => a(iao, status)),
iai => ((IAsyncOperation<TResult>)iai).GetResults(),
onProgress: null,
progress: null,
multiValue: false
);
}
/// <summary>
/// Converts a Windows Runtime asynchronous operation to an observable sequence reporting its result but ignoring its progress notifications.
/// Each observer subscribed to the resulting observable sequence will be notified about the operations's single result and its successful or exceptional completion.
/// </summary>
/// <typeparam name="TResult">The type of the asynchronous operation's result.</typeparam>
/// <typeparam name="TProgress">The type of the reported progress objects, which get ignored by this conversion.</typeparam>
/// <param name="source">Asynchronous action to convert.</param>
/// <returns>An observable sequence that notifies observers about the asynchronous operation's result value and completion.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
public static IObservable<TResult> ToObservable<TResult, TProgress>(this IAsyncOperationWithProgress<TResult, TProgress> source)
{
if (source == null)
throw new ArgumentNullException("source");
return source.ToObservable_(null, false);
}
/// <summary>
/// Converts a Windows Runtime asynchronous operation to an observable sequence reporting its result and reporting its progress through the supplied progress object.
/// Each observer subscribed to the resulting observable sequence will be notified about the operations's single result and its successful or exceptional completion.
/// </summary>
/// <typeparam name="TResult">The type of the asynchronous operation's result.</typeparam>
/// <typeparam name="TProgress">The type of the reported progress objects.</typeparam>
/// <param name="source">Asynchronous action to convert.</param>
/// <param name="progress">Progress object to receive progress notifications on.</param>
/// <returns>An observable sequence that notifies observers about the asynchronous operation's result value and completion.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="progress"/> is null.</exception>
public static IObservable<TResult> ToObservable<TResult, TProgress>(this IAsyncOperationWithProgress<TResult, TProgress> source, IProgress<TProgress> progress)
{
if (source == null)
throw new ArgumentNullException("source");
if (progress == null)
throw new ArgumentNullException("progress");
return source.ToObservable_(progress, false);
}
/// <summary>
/// Converts a Windows Runtime asynchronous operation to an observable sequence reporting its progress but ignoring its result value.
/// Each observer subscribed to the resulting observable sequence will be notified about the action's succesful or exceptional completion.
/// </summary>
/// <typeparam name="TResult">The type of the asynchronous operation's result, which gets ignored by this conversion.</typeparam>
/// <typeparam name="TProgress">The type of the reported progress objects.</typeparam>
/// <param name="source">Asynchronous action to convert.</param>
/// <returns>An observable sequence that produces progress values from the asynchronous operatin and notifies observers about the operations's completion.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
public static IObservable<TProgress> ToObservableProgress<TResult, TProgress>(this IAsyncOperationWithProgress<TResult, TProgress> source)
{
if (source == null)
throw new ArgumentNullException("source");
return Observable.Create<TProgress>(observer =>
{
var progress = observer.ToProgress();
var src = source.ToObservable_(progress, false);
return src.Subscribe(_ => { }, observer.OnError, observer.OnCompleted);
});
}
/// <summary>
/// Converts a Windows Runtime asynchronous operation to an observable sequence by retrieving the operation's results whenever progress is reported and when the operation completes.
/// Each observer subscribed to the resulting observable sequence will be notified about the action's succesful or exceptional completion.
/// </summary>
/// <typeparam name="TResult">The type of the asynchronous operation's result.</typeparam>
/// <typeparam name="TProgress">The type of the reported progress objects, which are used internally in the conversion but aren't exposed.</typeparam>
/// <param name="source">Asynchronous operation to convert.</param>
/// <returns>An observable sequence that notifies observers about the asynchronous operation's (incremental) result value(s) and completion.</returns>
/// <remarks>This conversion can be used with Windows Runtime APIs that support incremental retrieval of results during an asynchronous operation's execution.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
public static IObservable<TResult> ToObservableMultiple<TResult, TProgress>(this IAsyncOperationWithProgress<TResult, TProgress> source)
{
if (source == null)
throw new ArgumentNullException("source");
return source.ToObservable_(null, true);
}
/// <summary>
/// Converts a Windows Runtime asynchronous operation to an observable sequence by retrieving the operation's results whenever progress is reported and when the operation completes. The operation's progress is reported through the supplied progress object.
/// Each observer subscribed to the resulting observable sequence will be notified about the action's succesful or exceptional completion.
/// </summary>
/// <typeparam name="TResult">The type of the asynchronous operation's result.</typeparam>
/// <typeparam name="TProgress">The type of the reported progress objects.</typeparam>
/// <param name="source">Asynchronous operation to convert.</param>
/// <param name="progress">Progress object to receive progress notifications on.</param>
/// <returns>An observable sequence that notifies observers about the asynchronous operation's (incremental) result value(s) and completion.</returns>
/// <remarks>This conversion can be used with Windows Runtime APIs that support incremental retrieval of results during an asynchronous operation's execution.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="progress"/> is null.</exception>
public static IObservable<TResult> ToObservableMultiple<TResult, TProgress>(this IAsyncOperationWithProgress<TResult, TProgress> source, IProgress<TProgress> progress)
{
if (source == null)
throw new ArgumentNullException("source");
if (progress == null)
throw new ArgumentNullException("progress");
return source.ToObservable_(progress, true);
}
private static IObservable<TResult> ToObservable_<TResult, TProgress>(this IAsyncOperationWithProgress<TResult, TProgress> source, IProgress<TProgress> progress, bool supportsMultiple)
{
return new AsyncInfoToObservableBridge<TResult, TProgress>(
source,
(iai, a) => ((IAsyncOperationWithProgress<TResult, TProgress>)iai).Completed += new AsyncOperationWithProgressCompletedHandler<TResult, TProgress>((iao, status) => a(iao, status)),
iai => ((IAsyncOperationWithProgress<TResult, TProgress>)iai).GetResults(),
(iai, a) => ((IAsyncOperationWithProgress<TResult, TProgress>)iai).Progress += new AsyncOperationProgressHandler<TResult, TProgress>((iap, p) => a(iap, p)),
progress,
supportsMultiple
);
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,101 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
#if HAS_WINRT
using System.Reactive.Disposables;
using System.Reactive.Subjects;
using Windows.Foundation;
namespace System.Reactive.Windows.Foundation
{
class AsyncInfoToObservableBridge<TResult, TProgress> : ObservableBase<TResult>
{
private readonly Action<IAsyncInfo, Action<IAsyncInfo, AsyncStatus>> _onCompleted;
private readonly Func<IAsyncInfo, TResult> _getResult;
private readonly AsyncSubject<TResult> _subject;
public AsyncInfoToObservableBridge(IAsyncInfo info, Action<IAsyncInfo, Action<IAsyncInfo, AsyncStatus>> onCompleted, Func<IAsyncInfo, TResult> getResult, Action<IAsyncInfo, Action<IAsyncInfo, TProgress>> onProgress, IProgress<TProgress> progress, bool multiValue)
{
_onCompleted = onCompleted;
_getResult = getResult;
_subject = new AsyncSubject<TResult>();
if (onProgress != null)
{
onProgress(info, (iai, p) =>
{
if (multiValue && getResult != null)
_subject.OnNext(getResult(iai));
if (progress != null)
progress.Report(p);
});
}
Done(info, info.Status, true);
}
private void Done(IAsyncInfo info, AsyncStatus status, bool initial)
{
var error = default(Exception);
var result = default(TResult);
//
// Initial interactions with the IAsyncInfo object. Those could fail, which indicates
// a rogue implementation. Failure is just propagated out.
//
switch (status)
{
case AsyncStatus.Error:
error = info.ErrorCode;
if (error == null)
throw new InvalidOperationException("The asynchronous operation failed with a null error code.");
break;
case AsyncStatus.Canceled:
error = new OperationCanceledException();
break;
case AsyncStatus.Completed:
if (_getResult != null)
result = _getResult(info);
break;
default:
if (!initial)
throw new InvalidOperationException("The asynchronous operation completed unexpectedly.");
_onCompleted(info, (iai, s) => Done(iai, s, false));
return;
}
//
// Close as early as possible, before running continuations which could fail. In case of
// failure above, we don't close out the object in order to allow for debugging of the
// rogue implementation without losing state prematurely. Notice _getResults is merely
// an indirect call to the appropriate GetResults method, which is not supposed to throw.
// Instead, an Error status should be returned.
//
info.Close();
//
// Now we run the continuations, which could take a long time. Failure here is catastrophic
// and under control of the upstream subscriber.
//
if (error != null)
{
_subject.OnError(error);
}
else
{
if (_getResult != null)
_subject.OnNext(result);
_subject.OnCompleted();
}
}
protected override IDisposable SubscribeCore(IObserver<TResult> observer)
{
return _subject.Subscribe(observer);
}
}
}
#endif

View File

@@ -0,0 +1,21 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
#if HAS_WINRT
using Windows.Foundation;
namespace System.Reactive
{
/// <summary>
/// Represents a data stream signaling its elements by means of an event.
/// </summary>
/// <typeparam name="TSender">Sender type.</typeparam>
/// <typeparam name="TEventArgs">Event arguments type.</typeparam>
public interface IEventPatternSource<TSender, TEventArgs>
{
/// <summary>
/// Event signaling the next element in the data stream.
/// </summary>
event TypedEventHandler<TSender, TEventArgs> OnNext;
}
}
#endif

View File

@@ -0,0 +1,204 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
#if HAS_WINRT
using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Reactive.Subjects;
using System.Reactive.Threading.Tasks;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Threading.Tasks;
using Windows.Foundation;
namespace System.Reactive.Linq
{
/// <summary>
/// Provides a set of extension methods to expose observable sequences as Windows Runtime asynchronous actions and operations.
/// </summary>
public static class AsyncInfoObservable
{
#region IAsyncAction
/// <summary>
/// Creates a Windows Runtime asynchronous action that represents the completion of the observable sequence.
/// Upon cancellation of the asynchronous action, the subscription to the source sequence will be disposed.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <param name="source">Source sequence to expose as an asynchronous action.</param>
/// <returns>Windows Runtime asynchronous action object representing the completion of the observable sequence.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
public static IAsyncAction ToAsyncAction<TSource>(this IObservable<TSource> source)
{
if (source == null)
throw new ArgumentNullException("source");
return AsyncInfo.Run(ct => (Task)source.DefaultIfEmpty().ToTask(ct));
}
#region Progress
/// <summary>
/// Creates a Windows Runtime asynchronous action that represents the completion of the observable sequence, reporting incremental progress for each element produced by the sequence.
/// Upon cancellation of the asynchronous action, the subscription to the source sequence will be disposed.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <param name="source">Source sequence to expose as an asynchronous action.</param>
/// <returns>Windows Runtime asynchronous action object representing the completion of the observable sequence, reporting incremental progress for each source sequence element.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
public static IAsyncActionWithProgress<int> ToAsyncActionWithProgress<TSource>(this IObservable<TSource> source)
{
if (source == null)
throw new ArgumentNullException("source");
return AsyncInfo.Run<int>((ct, progress) =>
{
var i = 0;
return (Task)source.Do(_ => progress.Report(i++)).DefaultIfEmpty().ToTask(ct);
});
}
/// <summary>
/// Creates a Windows Runtime asynchronous action that represents the completion of the observable sequence, using a selector function to map the source sequence on a progress reporting sequence.
/// Upon cancellation of the asynchronous action, the subscription to the source sequence will be disposed.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <typeparam name="TProgress">The type of the elements in the progress sequence.</typeparam>
/// <param name="source">Source sequence to expose as an asynchronous action and to compute a progress sequence that gets reported through the asynchronous action.</param>
/// <param name="progressSelector">Selector function to map the source sequence on a progress reporting sequence.</param>
/// <returns>Windows Runtime asynchronous action object representing the completion of the result sequence, reporting progress computed through the progress sequence.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="progressSelector"/> is null.</exception>
public static IAsyncActionWithProgress<TProgress> ToAsyncActionWithProgress<TSource, TProgress>(this IObservable<TSource> source, Func<IObservable<TSource>, IObservable<TProgress>> progressSelector)
{
if (source == null)
throw new ArgumentNullException("source");
if (progressSelector == null)
throw new ArgumentNullException("progressSelector");
return AsyncInfo.Run<TProgress>((ct, progress) =>
{
return (Task)Observable.Create<TSource>(observer =>
{
var obs = Observer.Synchronize(observer);
var data = source.Publish();
var progressSubscription = progressSelector(data).Subscribe(progress.Report, obs.OnError);
var dataSubscription = data.DefaultIfEmpty().Subscribe(obs);
var connection = data.Connect();
return new CompositeDisposable(progressSubscription, dataSubscription, connection);
}).ToTask(ct);
});
}
#endregion
#endregion
#region IAsyncOperation<T>
/// <summary>
/// Creates a Windows Runtime asynchronous operation that returns the last element of the observable sequence.
/// Upon cancellation of the asynchronous operation, the subscription to the source sequence will be disposed.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <param name="source">Source sequence to expose as an asynchronous operation.</param>
/// <returns>Windows Runtime asynchronous operation object that returns the last element of the observable sequence.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
public static IAsyncOperation<TSource> ToAsyncOperation<TSource>(this IObservable<TSource> source)
{
if (source == null)
throw new ArgumentNullException("source");
return AsyncInfo.Run(ct => source.ToTask(ct));
}
/// <summary>
/// Creates a Windows Runtime asynchronous operation that returns the last element of the observable sequence, reporting incremental progress for each element produced by the sequence.
/// Upon cancellation of the asynchronous operation, the subscription to the source sequence will be disposed.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <param name="source">Source sequence to expose as an asynchronous operation.</param>
/// <returns>Windows Runtime asynchronous operation object that returns the last element of the observable sequence, reporting incremental progress for each source sequence element.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
public static IAsyncOperationWithProgress<TSource, int> ToAsyncOperationWithProgress<TSource>(this IObservable<TSource> source)
{
if (source == null)
throw new ArgumentNullException("source");
return AsyncInfo.Run<TSource, int>((ct, progress) =>
{
var i = 0;
return source.Do(_ => progress.Report(i++)).ToTask(ct);
});
}
#region Progress
/// <summary>
/// Creates a Windows Runtime asynchronous operation that returns the last element of the result sequence, reporting incremental progress for each element produced by the source sequence.
/// Upon cancellation of the asynchronous operation, the subscription to the source sequence will be disposed.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <typeparam name="TResult">The type of the elements in the result sequence.</typeparam>
/// <param name="source">Source sequence to compute a result sequence that gets exposed as an asynchronous operation.</param>
/// <param name="resultSelector">Selector function to map the source sequence on a result sequence.</param>
/// <returns>Windows Runtime asynchronous operation object that returns the last element of the result sequence, reporting incremental progress for each source sequence element.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="resultSelector"/> is null.</exception>
public static IAsyncOperationWithProgress<TResult, int> ToAsyncOperationWithProgress<TSource, TResult>(this IObservable<TSource> source, Func<IObservable<TSource>, IObservable<TResult>> resultSelector)
{
if (source == null)
throw new ArgumentNullException("source");
if (resultSelector == null)
throw new ArgumentNullException("resultSelector");
return AsyncInfo.Run<TResult, int>((ct, progress) =>
{
var i = 0;
return resultSelector(source.Do(_ => progress.Report(i++))).ToTask(ct);
});
}
/// <summary>
/// Creates a Windows Runtime asynchronous operation that returns the last element of the result sequence, using a selector function to map the source sequence on a progress reporting sequence.
/// Upon cancellation of the asynchronous operation, the subscription to the source sequence will be disposed.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <typeparam name="TResult">The type of the elements in the result sequence.</typeparam>
/// <typeparam name="TProgress">The type of the elements in the progress sequence.</typeparam>
/// <param name="source">Source sequence to compute a result sequence that gets exposed as an asynchronous operation and a progress sequence that gets reported through the asynchronous operation.</param>
/// <param name="resultSelector">Selector function to map the source sequence on a result sequence.</param>
/// <param name="progressSelector">Selector function to map the source sequence on a progress reporting sequence.</param>
/// <returns>Windows Runtime asynchronous operation object that returns the last element of the result sequence, reporting progress computed through the progress sequence.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="resultSelector"/> or <paramref name="progressSelector"/> is null.</exception>
public static IAsyncOperationWithProgress<TResult, TProgress> ToAsyncOperationWithProgress<TSource, TResult, TProgress>(this IObservable<TSource> source, Func<IObservable<TSource>, IObservable<TResult>> resultSelector, Func<IObservable<TSource>, IObservable<TProgress>> progressSelector)
{
if (source == null)
throw new ArgumentNullException("source");
if (resultSelector == null)
throw new ArgumentNullException("resultSelector");
if (progressSelector == null)
throw new ArgumentNullException("progressSelector");
return AsyncInfo.Run<TResult, TProgress>((ct, progress) =>
{
return Observable.Create<TResult>(observer =>
{
var obs = Observer.Synchronize(observer);
var data = source.Publish();
var progressSubscription = progressSelector(data).Subscribe(progress.Report, obs.OnError);
var dataSubscription = resultSelector(data).Subscribe(obs);
var connection = data.Connect();
return new CompositeDisposable(progressSubscription, dataSubscription, connection);
}).ToTask(ct);
});
}
#endregion
#endregion
}
}
#endif

View File

@@ -0,0 +1,101 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
#if HAS_WINRT
using System.Threading;
using Windows.Foundation;
namespace System.Reactive.Linq
{
/// <summary>
/// Provides a set of static methods for importing typed events from Windows Runtime APIs.
/// </summary>
public static partial class WindowsObservable
{
/// <summary>
/// Converts a typed event, conforming to the standard event pattern, to an observable sequence.
/// </summary>
/// <typeparam name="TSender">The type of the sender that raises the event.</typeparam>
/// <typeparam name="TResult">The type of the event data generated by the event.</typeparam>
/// <param name="addHandler">Action that attaches the given event handler to the underlying .NET event.</param>
/// <param name="removeHandler">Action that detaches the given event handler from the underlying .NET event.</param>
/// <returns>The observable sequence that contains data representations of invocations of the underlying typed event.</returns>
/// <exception cref="ArgumentNullException"><paramref name="addHandler"/> or <paramref name="removeHandler"/> is null.</exception>
/// <seealso cref="WindowsObservable.ToEventPattern"/>
public static IObservable<EventPattern<TSender, TResult>> FromEventPattern<TSender, TResult>(Action<TypedEventHandler<TSender, TResult>> addHandler, Action<TypedEventHandler<TSender, TResult>> removeHandler)
{
if (addHandler == null)
throw new ArgumentNullException("addHandler");
if (removeHandler == null)
throw new ArgumentNullException("removeHandler");
return Observable.Create<EventPattern<TSender, TResult>>(observer =>
{
var h = new TypedEventHandler<TSender, TResult>((sender, args) =>
{
observer.OnNext(new EventPattern<TSender, TResult>(sender, args));
});
addHandler(h);
return () =>
{
removeHandler(h);
};
});
}
/// <summary>
/// Converts a typed event, conforming to the standard event pattern, to an observable sequence.
/// </summary>
/// <typeparam name="TDelegate">The delegate type of the event to be converted.</typeparam>
/// <typeparam name="TSender">The type of the sender that raises the event.</typeparam>
/// <typeparam name="TResult">The type of the event data generated by the event.</typeparam>
/// <param name="conversion">A function used to convert the given event handler to a delegate compatible with the underlying typed event. The resulting delegate is used in calls to the addHandler and removeHandler action parameters.</param>
/// <param name="addHandler">Action that attaches the given event handler to the underlying .NET event.</param>
/// <param name="removeHandler">Action that detaches the given event handler from the underlying .NET event.</param>
/// <returns>The observable sequence that contains data representations of invocations of the underlying typed event.</returns>
/// <exception cref="ArgumentNullException"><paramref name="conversion"/> or <paramref name="addHandler"/> or <paramref name="removeHandler"/> is null.</exception>
/// <seealso cref="WindowsObservable.ToEventPattern"/>
public static IObservable<EventPattern<TSender, TResult>> FromEventPattern<TDelegate, TSender, TResult>(Func<TypedEventHandler<TSender, TResult>, TDelegate> conversion, Action<TDelegate> addHandler, Action<TDelegate> removeHandler)
{
if (conversion == null)
throw new ArgumentNullException("conversion");
if (addHandler == null)
throw new ArgumentNullException("addHandler");
if (removeHandler == null)
throw new ArgumentNullException("removeHandler");
return Observable.Create<EventPattern<TSender, TResult>>(observer =>
{
var h = conversion(new TypedEventHandler<TSender, TResult>((sender, args) =>
{
observer.OnNext(new EventPattern<TSender, TResult>(sender, args));
}));
addHandler(h);
return () =>
{
removeHandler(h);
};
});
}
/// <summary>
/// Exposes an observable sequence as an object with a typed event.
/// </summary>
/// <typeparam name="TSender">The type of the sender that raises the event.</typeparam>
/// <typeparam name="TEventArgs">The type of the event data generated by the event.</typeparam>
/// <param name="source">Observable source sequence.</param>
/// <returns>The event source object.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
public static IEventPatternSource<TSender, TEventArgs> ToEventPattern<TSender, TEventArgs>(this IObservable<EventPattern<TSender, TEventArgs>> source)
{
if (source == null)
throw new ArgumentNullException("source");
return new EventPatternSource<TSender, TEventArgs>(source, (h, evt) => h(evt.Sender, evt.EventArgs));
}
}
}
#endif

View File

@@ -0,0 +1,103 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
#if HAS_WINRT
using System.Reactive.Windows.Foundation;
using System.Threading;
using Windows.Foundation;
namespace System.Reactive.Linq
{
public static partial class WindowsObservable
{
/// <summary>
/// Projects each element of an observable sequence to a Windows Runtime asynchronous operation and merges all of the asynchronous operation results into one observable sequence.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <typeparam name="TResult">The type of the result produced by the projected asynchronous operations and the elements in the merged result sequence.</typeparam>
/// <param name="source">An observable sequence of elements to project.</param>
/// <param name="selector">A transform function to apply to each element.</param>
/// <returns>An observable sequence whose elements are the result of the asynchronous operations executed for each element of the input sequence.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
/// <remarks>This overload supports composition of observable sequences and Windows Runtime asynchronous operations, without requiring manual conversion of the asynchronous operations to observable sequences using <see cref="AsyncInfoObservableExtensions.ToObservable&lt;TResult&gt;(IAsyncOperation&lt;TResult&gt;)"/>.</remarks>
public static IObservable<TResult> SelectMany<TSource, TResult>(this IObservable<TSource> source, Func<TSource, IAsyncOperation<TResult>> selector)
{
if (source == null)
throw new ArgumentNullException("source");
if (selector == null)
throw new ArgumentNullException("selector");
return source.SelectMany(x => selector(x).ToObservable());
}
/// <summary>
/// Projects each element of an observable sequence to a Windows Runtime asynchronous operation and merges all of the asynchronous operation results into one observable sequence.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <typeparam name="TResult">The type of the result produced by the projected asynchronous operations and the elements in the merged result sequence.</typeparam>
/// <typeparam name="TProgress">The type of the reported progress objects, which get ignored by this query operator.</typeparam>
/// <param name="source">An observable sequence of elements to project.</param>
/// <param name="selector">A transform function to apply to each element.</param>
/// <returns>An observable sequence whose elements are the result of the asynchronous operations executed for each element of the input sequence.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
/// <remarks>This overload supports composition of observable sequences and Windows Runtime asynchronous operations, without requiring manual conversion of the asynchronous operations to observable sequences using <see cref="AsyncInfoObservableExtensions.ToObservable&lt;TResult&gt;(IAsyncOperation&lt;TResult&gt;)"/>.</remarks>
public static IObservable<TResult> SelectMany<TSource, TResult, TProgress>(this IObservable<TSource> source, Func<TSource, IAsyncOperationWithProgress<TResult, TProgress>> selector)
{
if (source == null)
throw new ArgumentNullException("source");
if (selector == null)
throw new ArgumentNullException("selector");
return source.SelectMany(x => selector(x).ToObservable());
}
/// <summary>
/// Projects each element of an observable sequence to a Windows Runtime asynchronous operation, invokes the result selector for the source element and the asynchronous operation result, and merges the results into one observable sequence.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <typeparam name="TAsyncOperationResult">The type of the results produced by the projected asynchronous operations.</typeparam>
/// <typeparam name="TResult">The type of the elements in the result sequence, obtained by using the selector to combine source sequence elements with their corresponding intermediate asynchronous operation results.</typeparam>
/// <param name="source">An observable sequence of elements to project.</param>
/// <param name="asyncOperationSelector">A transform function to apply to each element.</param>
/// <param name="resultSelector">A transform function to apply to each element of the intermediate sequence.</param>
/// <returns>An observable sequence whose elements are the result of obtaining an asynchronous operation for each element of the input sequence and then mapping the asynchronous operation's result and its corresponding source element to a result element.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="asyncOperationSelector"/> or <paramref name="resultSelector"/> is null.</exception>
/// <remarks>This overload supports using LINQ query comprehension syntax in C# and Visual Basic to compose observable sequences and Windows Runtime asynchronous operations, without requiring manual conversion of the asynchronous operations to observable sequences using <see cref="AsyncInfoObservableExtensions.ToObservable&lt;TResult&gt;(IAsyncOperation&lt;TResult&gt;)"/>.</remarks>
public static IObservable<TResult> SelectMany<TSource, TAsyncOperationResult, TResult>(this IObservable<TSource> source, Func<TSource, IAsyncOperation<TAsyncOperationResult>> asyncOperationSelector, Func<TSource, TAsyncOperationResult, TResult> resultSelector)
{
if (source == null)
throw new ArgumentNullException("source");
if (asyncOperationSelector == null)
throw new ArgumentNullException("asyncOperationSelector");
if (resultSelector == null)
throw new ArgumentNullException("resultSelector");
return source.SelectMany(x => asyncOperationSelector(x).ToObservable(), resultSelector);
}
/// <summary>
/// Projects each element of an observable sequence to a Windows Runtime asynchronous operation, invokes the result selector for the source element and the asynchronous operation result, and merges the results into one observable sequence.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <typeparam name="TAsyncOperationResult">The type of the results produced by the projected asynchronous operations.</typeparam>
/// <typeparam name="TAsyncOperationProgress">The type of the reported progress objects, which get ignored by this query operator.</typeparam>
/// <typeparam name="TResult">The type of the elements in the result sequence, obtained by using the selector to combine source sequence elements with their corresponding intermediate asynchronous operation results.</typeparam>
/// <param name="source">An observable sequence of elements to project.</param>
/// <param name="asyncOperationSelector">A transform function to apply to each element.</param>
/// <param name="resultSelector">A transform function to apply to each element of the intermediate sequence.</param>
/// <returns>An observable sequence whose elements are the result of obtaining an asynchronous operation for each element of the input sequence and then mapping the asynchronous operation's result and its corresponding source element to a result element.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="asyncOperationSelector"/> or <paramref name="resultSelector"/> is null.</exception>
/// <remarks>This overload supports using LINQ query comprehension syntax in C# and Visual Basic to compose observable sequences and Windows Runtime asynchronous operations, without requiring manual conversion of the asynchronous operations to observable sequences using <see cref="AsyncInfoObservableExtensions.ToObservable&lt;TResult&gt;(IAsyncOperation&lt;TResult&gt;)"/>.</remarks>
public static IObservable<TResult> SelectMany<TSource, TAsyncOperationResult, TAsyncOperationProgress, TResult>(this IObservable<TSource> source, Func<TSource, IAsyncOperationWithProgress<TAsyncOperationResult, TAsyncOperationProgress>> asyncOperationSelector, Func<TSource, TAsyncOperationResult, TResult> resultSelector)
{
if (source == null)
throw new ArgumentNullException("source");
if (asyncOperationSelector == null)
throw new ArgumentNullException("asyncOperationSelector");
if (resultSelector == null)
throw new ArgumentNullException("resultSelector");
return source.SelectMany(x => asyncOperationSelector(x).ToObservable(), resultSelector);
}
}
}
#endif

View File

@@ -0,0 +1,35 @@
using System;
using System.Reflection;
using System.Resources;
using System.Runtime.InteropServices;
using System.Security;
[assembly: AssemblyTitle("System.Reactive.WindowsRuntime")]
// Notice: same description as in the .nuspec files; see Source/Rx/Setup/NuGet
[assembly: AssemblyDescription("Windows Runtime extensions library for Rx. Contains scheduler functionality and various bridges for the Windows Runtime.")]
#if DEBUG
[assembly: AssemblyConfiguration("Debug")]
#else
[assembly: AssemblyConfiguration("Retail")]
#endif
[assembly: AssemblyCompany("Microsoft Open Technologies, Inc.")]
[assembly: AssemblyProduct("Reactive Extensions")]
[assembly: AssemblyCopyright("\x00a9 Microsoft Open Technologies, Inc. All rights reserved.")]
[assembly: NeutralResourcesLanguage("en-US")]
#if !PLIB
[assembly: ComVisible(false)]
#endif
#if HAS_APTCA && NO_CODECOVERAGE
[assembly: AllowPartiallyTrustedCallers]
#endif
// ===========================================================================
// DO NOT EDIT OR REMOVE ANYTHING BELOW THIS COMMENT.
// Version numbers are automatically generated in the msbuild files based on regular expressions
// ===========================================================================
[assembly: AssemblyVersion("2.2.0.0")]
[assembly: AssemblyFileVersion("2.2.0.0")]
[assembly: AssemblyInformationalVersion("2.2.0.0")]

View File

@@ -0,0 +1,107 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{EE655A70-A899-4B38-84D3-FB9F63A8C661}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>System.Reactive</RootNamespace>
<AssemblyName>System.Reactive.WindowsRuntime</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProductSignAssembly>true</ProductSignAssembly>
<CodeAnalysisRuleSet>..\Rx.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'ReleaseXBLV|AnyCPU'">
<OutputPath>bin\ReleaseXBLV\</OutputPath>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'DebugXBLV|AnyCPU'">
<OutputPath>bin\DebugXBLV\</OutputPath>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug45|AnyCPU'">
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release45|AnyCPU'">
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug40|AnyCPU'">
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release40|AnyCPU'">
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'DebugSL5|AnyCPU'">
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'ReleaseSL5|AnyCPU'">
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'DebugWP7|AnyCPU'">
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'ReleaseWP7|AnyCPU'">
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug35|AnyCPU'">
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release35|AnyCPU'">
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'DebugSL3|AnyCPU'">
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'ReleaseSL3|AnyCPU'">
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'DebugSL4|AnyCPU'">
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'ReleaseSL4|AnyCPU'">
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'DebugXNA4|AnyCPU'">
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'ReleaseXNA4|AnyCPU'">
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<Import Project="..\Common.targets" />
<PropertyGroup>
<DocumentationFile>$(OutputPath)\$(AssemblyName).XML</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
</ItemGroup>
<ItemGroup>
<Compile Include="EventPatternSource.cs" />
<Compile Include="Foundation\AsyncInfoExtensions.cs" />
<Compile Include="Linq\AsyncInfoObservable.cs" />
<Compile Include="Foundation\AsyncInfoToObservableBridge.cs" />
<Compile Include="IEventPatternSource.cs" />
<Compile Include="Linq\WindowsObservable.StandardSequenceOperators.cs" />
<Compile Include="Linq\WindowsObservable.Events.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\System.Reactive.Core\System.Reactive.Core.csproj">
<Project>{4E516F10-DA7A-4D43-963E-A93865ABEA5B}</Project>
<Name>System.Reactive.Core</Name>
</ProjectReference>
<ProjectReference Include="..\System.Reactive.Interfaces\System.Reactive.Interfaces.csproj">
<Project>{9E9B9C60-98B0-40FA-9C2B-1218D417CAA4}</Project>
<Name>System.Reactive.Interfaces</Name>
</ProjectReference>
<ProjectReference Include="..\System.Reactive.Linq\System.Reactive.Linq.csproj">
<Project>{63252ae9-5186-45ca-bfcd-fa51c6b66a43}</Project>
<Name>System.Reactive.Linq</Name>
</ProjectReference>
</ItemGroup>
<Import Project="..\Import.targets" />
</Project>