제네릭을 사용하도록이 프로그램을 변환하려고합니다. 그러나 라인에Generics and Rx
foreach (var observer in observerList)
{
observer.OnNext(observer);
}
내가 얻을 :
Cannot convert from System.IObserver<T> to T
프로그램 :
public sealed class EnumerableObservable<T> : IObservable<T>, IDisposable
{
private readonly IEnumerable<T> enumerable;
public EnumerableObservable(IEnumerable<T> enumerable)
{
this.enumerable = enumerable;
this.cancellationSource = new CancellationTokenSource();
this.cancellationToken = cancellationSource.Token;
this.workerTask = Task.Factory.StartNew(() =>
{
foreach (var value in this.enumerable)
{
//if task cancellation triggers, raise the proper exception
//to stop task execution
cancellationToken.ThrowIfCancellationRequested();
foreach (var observer in observerList)
{
observer.OnNext(observer);
}
}
}, this.cancellationToken);
}
//the cancellation token source for starting stopping
//inner observable working thread
private readonly CancellationTokenSource cancellationSource;
//the cancellation flag
private readonly CancellationToken cancellationToken;
//the running task that runs the inner running thread
private readonly Task workerTask;
//the observer list
private readonly List<IObserver<T>> observerList = new List<IObserver<T>>();
public IDisposable Subscribe(IObserver<T> observer)
{
observerList.Add(observer);
//subscription lifecycle missing
//for readability purpose
return null;
}
public void Dispose()
{
//trigger task cancellation
//and wait for acknoledge
if (!cancellationSource.IsCancellationRequested)
{
cancellationSource.Cancel();
while (!workerTask.IsCanceled)
Thread.Sleep(100);
}
cancellationSource.Dispose();
workerTask.Dispose();
foreach (var observer in observerList)
observer.OnCompleted();
}
}
public sealed class ConsoleStringObserver<T> : IObserver<T>
{
public void OnCompleted()
{
Console.WriteLine("-> END");
}
public void OnError(Exception error)
{
Console.WriteLine("-> {0}", error.Message);
}
public void OnNext(T value)
{
Console.WriteLine("-> {0}", value.ToString());
}
}
class Program
{
static void Main(string[] args)
{
//we create a variable containing the enumerable
//this does not trigger item retrieval
//so the enumerator does not begin flowing datas
var enumerable = EnumerateValuesFromSomewhere();
using (var observable = new EnumerableObservable<string>(enumerable))
using (var observer = observable.Subscribe(new ConsoleStringObserver<string>()))
{
//wait for 2 seconds than exit
Thread.Sleep(2000);
}
Console.WriteLine("Press RETURN to EXIT");
Console.ReadLine();
}
static IEnumerable<string> EnumerateValuesFromSomewhere()
{
var random = new Random(DateTime.Now.GetHashCode());
while (true) //forever
{
//returns a random integer number as string
yield return random.Next().ToString();
//some throttling time
Thread.Sleep(100);
}
}
}
LOL. 오타. 고마워. :-) – Ivan