I am using one delegate and event for the same as below:
public delegate void DelgSampledelegate(string status);
public static event DelgSampledelegate sampleEvent;
sampleEvent += new DelgSampledelegate(sample_method);
public void sample_method(string value)
{}
Now I wanted to use Rx Extension for above delegate. So I tried below code to create object of Observable.FromEvent
var objDataUpdated = Observable.FromEvent(h => sampleEvent += h, h => sampleEvent -= h);
var movesSubscription = objDataUpdated.Subscribe(evt => evt.ToString());
My aim is to call 'sample_method' function as I was calling earlier.I know it may be done either via subscribe.Please guide me proper way to do it.
Can't see that you're missing much except the type parameters and actually raising an event to test it:
var objDataUpdated = Observable.FromEvent<DelgSampledelegate, string>(
h => sampleEvent += h,
h => sampleEvent -= h);
var movesSubscription = objDataUpdated.Subscribe(x => sample_method(x));
// note the preceding line can be shortened to finish
// .Subscribe(sample_method) but I didn't want to make too many leaps
// raise a sampleEvent, will call sample_method("Test")
sampleEvent("Test");
See How to use Observable.FromEvent instead of FromEventPattern and avoid string literal event names for a comprehensive explanation of FromEvent - although note the form in this answer needs no conversion function because DelgSampledelegate's signature matches the required OnNext signature.
Related
I am trying the async examples from the GNOME project site. I get the follwoing warning which I don't under stand on how to fix.
async.vala:8.2-8.17: warning: delegates with scope="async" must be owned
Code
async double do_calc_in_bg(double val) throws ThreadError {
SourceFunc callback = do_calc_in_bg.callback;
double[] output = new double[1];
// Hold reference to closure to keep it from being freed whilst
// thread is active.
// WARNING HERE
ThreadFunc<bool> run = () => {
// Perform a dummy slow calculation.
// (Insert real-life time-consuming algorithm here.)
double result = 0;
for (int a = 0; a<100000000; a++)
result += val * a;
output[0] = result;
Idle.add((owned) callback);
return true;
};
new Thread<bool>("thread-example", run);
yield;
return output[0];
}
void main(string[] args) {
var loop = new MainLoop();
do_calc_in_bg.begin(0.001, (obj, res) => {
try {
double result = do_calc_in_bg.end(res);
stderr.printf(#"Result: $result\n");
} catch (ThreadError e) {
string msg = e.message;
stderr.printf(#"Thread error: $msg\n");
}
loop.quit();
});
loop.run();
}
The warning is pointing at the run variable inside the async function. Who or what needs to be owned? The reference to the closure?
The delegate needs to have a well defined owner all the time. The error message is a bit misleading.
To fix it you have to explicitly transfer the ownership from the delegate to the thread constructor:
new Thread<bool>("thread-example", (owned) run);
Instead of
new Thread<bool>("thread-example", run);
See also: https://wiki.gnome.org/Projects/Vala/Tutorial#Ownership
PS: The generated C code is fine in both cases. (at least with valac 0.46.6)
I am trying to figure out why I am getting the following exception when Im mocking my very simple interface.
System.Reflection.TargetParameterCountException: Parameter count
mismatch.
var zoneLocator = new Mock<IZoneLocator<ZoneInfo>>();
zoneLocator
.Setup(zl => zl.GetZoneInfo(
It.IsAny<double>(), It.IsAny<double>()))
.Returns((ZoneInfo zoneInfo) =>
Task.FromResult(zoneInfo));
var z = zoneLocator.Object.GetZoneInfo(1, 1);
interface:
public interface IZoneLocator<T>
{
Task<T> GetZoneInfo(double latitude, double longitude);
}
The overload of Returns that expects a Func is expecting a function that has the same inputs as the inputs of your mocked method. This allows you to alter the return value based on the inputs to the method.
So, to fix this, change your setup to this:
zoneLocator
.Setup(zl => zl.GetZoneInfo(It.IsAny<double>(), It.IsAny<double>()))
.Returns((double latitude, double longitude) =>
Task.FromResult(/* TODO: create a timezone somehow*/));
I'm new to RX, and I have my desired scenario working well, but it seems to me there must be a simpler or more elegant way to achieve this. What I have is an IObservable<T> and I want to subscribe to it in such a way that I end up with an IObservable<U>, by triggering an asynchronous operation that generates a U for each T it sees.
What I have so far (that works great, but seems cumbersome) uses an intermediate event stream and goes something like this:
public class Converter {
public event EventHandler<UArgs> UDone;
public IConnectableObservable<U> ToUs(IObservable<T> ts) {
var us = Observable.FromEvent<UArgs>(this, "UDone").Select(e => e.EventArgs.U).Replay();
ts.Subscribe(t => Observable.Start(() => OnUDone(new U(t))));
return us;
}
private void OnUDone(U u) {
var uDone = UDone;
if (uDone != null) {
uDone(this, u);
}
}
}
...
var c = new Converter();
IConnectableObservable<T> ts = ...;
var us = c.ToUs(ts);
us.Connect();
...
I'm sure I'm missing a much simpler way to do this...
SelectMany should do what you need, to flatten out the IO<IO<T>>
Observable.Range(1, 10)
.Select(ii => Observable.Start(() =>
string.Format("{0} {1}", ii, Thread.CurrentThread.ManagedThreadId)))
.SelectMany(id=>id)
.Subscribe(Console.WriteLine);
This is exactly what SelectMany is for:
IObservable<int> ts
IObservable<string> us = ts.SelectMany(t => StartAsync(t));
us.Subscribe(u =>
Console.WriteLine("StartAsync completed with {0}", u));
...
private IObservable<string> StartAsync(int t)
{
return Observable.Return(t.ToString())
.Delay(TimeSpan.FromSeconds(1));
}
Keep in mind that if StartAsync has a variable completion time, you may receive the output values in a different order from the input values.
Given the following interface
public interface ISomething {
void DoMany(string[] strs);
void DoManyRef(ref string[] strs);
}
I would like to verify that the DoManyRef method is called, and passed any string array as the strs parameter. The following test fails:
public void CanVerifyMethodsWithArrayRefParameter() {
var a = new Mock<ISomething>().Object;
var strs = new string[0];
a.DoManyRef(ref strs);
var other = It.IsAny<string[]>();
Mock.Get(a).Verify(t => t.DoManyRef(ref other));
}
While the following not requiring the array passed by reference passes:
public void CanVerifyMethodsWithArrayParameter() {
var a = new Mock<ISomething>().Object;
a.DoMany(new[] { "a", "b" });
Mock.Get(a).Verify(t => t.DoMany(It.IsAny<string[]>()));
}
I am not able to change the interface to eliminate the by reference requirement.
For verifying against ref arguments, you need to pass the actual instance into the verify call. This means your first test should appear as follows:
[Test]
public void CanVerifyMethodsWithArrayRefParameter()
{
var a = new Mock<ISomething>().Object;
var strs = new string[0];
a.DoManyRef(ref strs);
Mock.Get(a).Verify(t => t.DoManyRef(ref strs));
}
The final sentence of the question leads me to believe you might not be able to make that change, but that is what is required for the Verify call to succeed. Hope this helps.
Hi i need to make a VectorIterator, so i need to accept a Vector with any type. I am currently trying to define the type as * like so:
var collection:Vector.<*> = new Vector<*>()
But the compiler is complaining that the type "is not a compile time constant". i know a bug exists with the Vector class where the error reporting, reports the wrong type as missing, for example:
var collection:Vector.<Sprite> = new Vector.<Sprite>()
if Sprite was not imported, the compiler would complain that it cannot find the Vector class. I wonder if this is related?
So it looks like the answer is there is no way to implicitly cast a Vector of a type to valid super type. It must be performed explicitly with the global Vector.<> function.
So my actual problem was a mix of problems :)
It is correct to use Vector. as a generic reference to another Vector, but, it cannot be performed like this:
var spriteList:Vector.<Sprite> = new Vector.<Sprite>()
var genericList:Vector.<Object> = new Vector.<Object>()
genericList = spriteList // this will cause a type casting error
The assignment should be performed using the global Vector() function/cast like so:
var spriteList:Vector.<Sprite> = new Vector.<Sprite>()
var genericList:Vector.<Object> = new Vector.<Object>()
genericList = Vector.<Object>(spriteList)
It was a simple case of me not reading the documentation.
Below is some test code, I would expect the Vector. to cast implicitly to Vector.<*>.
public class VectorTest extends Sprite
{
public function VectorTest()
{
// works, due to <*> being strictly the same type as the collection in VectorContainer
var collection:Vector.<*> = new Vector.<String>()
// compiler complains about implicit conversion of <String> to <*>
var collection:Vector.<String> = new Vector.<String>()
collection.push("One")
collection.push("Two")
collection.push("Three")
for each (var eachNumber:String in collection)
{
trace("eachNumber: " + eachNumber)
}
var vectorContainer:VectorContainer = new VectorContainer(collection)
while(vectorContainer.hasNext())
{
trace(vectorContainer.next)
}
}
}
public class VectorContainer
{
private var _collection:Vector.<*>
private var _index:int = 0
public function VectorContainer(collection:Vector.<*>)
{
_collection = collection
}
public function hasNext():Boolean
{
return _index < _collection.length
}
public function get next():*
{
return _collection[_index++]
}
}
[Bindable]
public var selectedItems:Vector.<Category>;
public function selectionChange(items:Vector.<Object>):void
{
selectedItems = Vector.<Category>(items);
}
I believe you can refer to an untyped Vector by just calling it Vector (no .<>)
With Apache Flex 4.11.0, you can already do what you want. It might have been there since 4.9.0, but I have not tried that before.
var collection:Vector.<Object> = new Vector.<Object>()
maybe?
But i'm just speculating, haven't tried it.
var collection:Vector.<Object> = new Vector.<Object>()
but only on targeting flash player 10 cs4