tags:

views:

55

answers:

4

Hello,

I want to access a webservice:getMonitorData() , on creationcomplete and returns an array, in an infinite loop so that the getIndex0.text is updated each time.

Flex is not able to handle an infinite loop and gives a timeout error 1502. If I run the for loop until i<2000 or so it works fine.

How can replace the loop so that my webservice is accessed continiously and the result is shown in getIndex0.text.

This is how my application looks like:

<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" 
         xmlns:s="library://ns.adobe.com/flex/spark" 
         xmlns:mx="library://ns.adobe.com/flex/mx" width="400" height="300" 
         xmlns:plcservicebean="server.services.plcservicebean.*"
         creationComplete="clientMonitor1()">
    <fx:Script>
        <![CDATA[
            import mx.collections.ArrayCollection;
            import mx.controls.Alert;
            import mx.rpc.CallResponder;
            import mx.rpc.events.FaultEvent;
            import mx.rpc.events.ResultEvent;


            [Bindable] public var dbl0:Number;

//-----------Infinite Loop, Works fine if condition = i<2000------------------------
            public function clientMonitor1():void{
                for(var i:int = 0; ; i++){
                    clientMonitor();                    
                }
            }

            public function clientMonitor():void{
                var callResp:CallResponder = new CallResponder();
                callResp.addEventListener(ResultEvent.RESULT, monitorResult);
                callResp.addEventListener(FaultEvent.FAULT, monitorFault);
                callResp.token = plcServiceBean.getMonitorData();
            }

            public function monitorResult(event:ResultEvent):void{
                var arr:ArrayCollection = event.result as ArrayCollection;
                dbl0 = arr[0].value as Number;
            }

            protected function monitorFault(event:FaultEvent):void{
                Alert.show(event.fault.faultString, "Error while monitoring Data ");
            }
        ]]>
    </fx:Script>
    <fx:Declarations>
        <plcservicebean:PlcServiceBean id = "plcServiceBean" 
                                       showBusyCursor="true" 
                                       fault="Alert.show(event.fault.faultString + '\n' + event.fault.faultDetail)" />
    </fx:Declarations>

    <mx:Form x="52" y="97" 
             label="Double">
        <mx:FormItem label = "getMonitorValue">
            <s:TextInput id = "getIndex0"
                         text = "{dbl0}"/>
        </mx:FormItem>
    </mx:Form>

</s:Group>
+1  A: 

Use a Timer.

Start the timer. When it triggers, stop the timer, make the call. When the call comes back, start the timer again. Repeat. This type of async/delayed timer loop will not use up cpu or halt other code.

Sam
A: 

It sounds to me like you need something like LifeCycle data services which will allow you to keep a socket open to the server and allow for push notifications from the server to the client.

Continuously hitting a remote web service just seems like a horribly bad idea to me.

www.Flextras.com
A: 

You could implement pseudo-recursion by adding an event listener that calls clientMonitor() and then raise that same event at the end of clientMonitor(). Just call clientMonitor() once to start the process.

Christopher Parker
This will not work: event handlers are synchronous, so you'll just be recursing for ever (or until you get a stack overflow) rather than looping for ever.
Andrew Aylett
+4  A: 

Your problem is that your loop runs synchronously while the actual web service calls are asynchronous. Flex uses a frame-based execution model and only has a single thread of execution -- when you make a call to the webservice, it initiates the connection and returns immediately. Looping forever, then, means that you'll never actually get to the next frame, where the result could be processed. Looping 2000 times means you spawn 2000 connections straight away, which will be queued up as you're not allowed to make that many connections at once. They will then complete over the next few minutes.

The way to do what you want to do is probably to wait until one request is complete before firing the next. To achieve this, you can call clientMonitor() from the end of your event handlers, or set up an extra event handler specifically to call clientMonitor() when the request completes.

Andrew Aylett
Thank you Andrew, I generated my web service connection classes using Data->Connect to webservice. The generated classes do not have an event handler. Can you please give me an example how to generate one. I want to monitor the web service clientMonitor() continuously.
H P
@H P: I'm afraid I've never used the web-service code generation tools, sorry.
Andrew Aylett