External interface & Form.Close() Problem

.NET Edition of the F-IN-BOX
Silvia Tosolini
Posts: 9
Joined: Fri Sep 08, 2006 10:45 am

External interface & Form.Close() Problem

Postby Silvia Tosolini » Fri Oct 13, 2006 8:21 am

Hi, I'm working with FlashPlayerControl (licensed version, for eTree/Etnoteam company - Treviso - Italy), .net framework 2.0, C#, Visual Studio 2005.

I'm using a FlashPlayerControlLibrary.FlashPlayerForm with an swf movie embedded. Using external interface, the swf movie makes a various number of function calls to the the .net methods provided and everything works fine.
I'm getting a serious problem when I implement a method that closes the current form:
private void MyExitMethod()
{
this.Close();
}

The behaviour looks like this:
- when calling MyExitMethod() directly from .net FlashPlayerForm everything works fine (I used an override of the mousewheel event to call MyExitMethod ).
- when calling MyExitMethod() as a reply to a flash request, MyExitMethod is executed but then I get a general error "Attempted to read or write protected memory. This is often an indication that other memory is corrupt." This exception is raised on the main thread of my application ( on the Application.Run() istruction... ).

I was able to reproduce this behaviour on your sample application Sample7_ExternalInterface (even if there you use FlashPlayerControlLibrary.FlashPlayerControl instead of the FlashPlayerControlLibrary.FlashPlayerForm). I can send you the updated sample as an attachment of this message.

I suppose that FlashPlayerControlLibrary doesn't release some objects, I really don't know what to do, I've tried a call to Marshal.Release but I cant' call this on a FlashPlayerForm.

Thanks in advance,
have a nice day

Softanics
Site Admin
Posts: 1402
Joined: Sat Sep 18, 2004 3:03 am
Location: Russia, St. Petersburg
Contact:

Postby Softanics » Fri Oct 13, 2006 10:41 am

Thank you for your question.

The simplest way to solve the problem is to use timer:

Code: Select all


private void MyExitMethod()
{
// this.Close();

   // Create a new Timer with Interval set to 1 second.
   System.Timers.Timer aTimer = new System.Timers.Timer(1000);
   aTimer.Elapsed+=new ElapsedEventHandler(OnTimedEvent);
   // Only raise the event the first time Interval elapses.
   aTimer.AutoReset = false;
   aTimer.Enabled = true;
}

private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
   this.Close();
}



In the flash event handlers you can't destroy flash control instance, load another movie into flash player and, probably, do some other things.
Best regards, Artem A. Razin,
F-IN-BOX support
Ask your question here: http://www.f-in-box.com/support.html

Silvia Tosolini
Posts: 9
Joined: Fri Sep 08, 2006 10:45 am

Postby Silvia Tosolini » Fri Oct 13, 2006 4:09 pm

Hi Softanics, thank you for your help.

The code you provided, as written above, raises a "Cross-thread operation not valid" exception.
I solved the problem using delegates and now the close form operation seems working. Here the code:

Code: Select all

   
delegate void Call_CloseCloseCallback();
......
private void MyExitMethod()
        {
            // this.Close();

            // Create a new Timer with Interval set to 1 second.
            System.Timers.Timer aTimer = new System.Timers.Timer(1000);
            aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
            // Only raise the event the first time Interval elapses.
            aTimer.AutoReset = false;
            aTimer.Enabled = true;
        }

private void OnTimedEvent(object source, ElapsedEventArgs e)
        {   
            //this.Close();   
            Call_CloseClose();                   
        }       

private void CloseClose()
        {
            this.Close();
        }

private void Call_CloseClose()
        {
            if (this.InvokeRequired)
            {
                Call_CloseCloseCallback d = new Call_CloseCloseCallback(CloseClose);
                this.Invoke(d, new object[] { });
            }
            else
            {
               CloseClose();
            }
        }


Anyway I have some questions for you:
1. What is FlashPlayerControlLibrary doing during those 1000 msecs?
2. Is always 1000 msecs enough? (I'm thinking about different machine configurations) Should I extend the timer period?
3. Do you know any other side-effect making my application behave like this?

Thanks,
Greetings
Silvia

Softanics
Site Admin
Posts: 1402
Joined: Sat Sep 18, 2004 3:03 am
Location: Russia, St. Petersburg
Contact:

Postby Softanics » Fri Oct 13, 2006 4:20 pm

Silvia Tosolini wrote:1. What is FlashPlayerControlLibrary doing during those 1000 msecs?


Application processes messages... I think it's incorrect question.

Silvia Tosolini wrote:2. Is always 1000 msecs enough? (I'm thinking about different machine configurations) Should I extend the timer period?


Use any value. Even 1 ms would be enough. Using timer is only to close the form (and destroy FlashPlayerControl instance!) not in the event handler. You can't destroy FlashPlayerControl inside the handler of flashcall.

Silvia Tosolini wrote:3. Do you know any other side-effect making my application behave like this?


Don't destroy FlashPlayerControl instance in handlers of flash events. Don't load a movie into flash player in the handlers. All this limitations related with flash player internals, FlashPlayerControl is a just wrapper, we can't change this behavior.
Best regards, Artem A. Razin,

F-IN-BOX support

Ask your question here: http://www.f-in-box.com/support.html

Silvia Tosolini
Posts: 9
Joined: Fri Sep 08, 2006 10:45 am

Postby Silvia Tosolini » Mon Oct 16, 2006 8:06 am

Thank you for support and answers, now everything works :D

Silvia Tosolini
Posts: 9
Joined: Fri Sep 08, 2006 10:45 am

Postby Silvia Tosolini » Sat Nov 11, 2006 9:08 am

Hi Softanics, unfortunately the problem is not solved at all.
Everything works correctly on my machine, but on some machines belonging to my customer it does not.
Sometimes (notice: not always) they get the usual exception "Attempted to read or write protected memory. This is often an indication that other memory is corrupt."
I've implemented the form closing exactly as written in my previous post. Then I've tried using a thread instead of the timered-thread you suggested, but the situation is still the same. Anyway I post here the code:

Code: Select all

private void MyExitMethod()
{   
     Thread myExitThread = new Thread(new ParameterizedThreadStart(ExitThread));
     myExitThread.Start("exit");           
}

public void ExitThread(object objID)
{
     Call_CloseClose();
}

private void CloseClose()
{
     TranslucencyForm.Close();
}

private void Call_CloseClose()
{
     if (TranslucencyForm.InvokeRequired)
     {
         Call_CloseCloseCallback d = new Call_CloseCloseCallback(CloseClose);
         TranslucencyForm.Invoke(d, new object[] { });
     }
     else
     {
         CloseClose();
     }
}

Do you have any idea about this? Why does the form closing code behave in a different way on different machine configurations?
Can be useful for you if I ask to my customer all information about the configuration of the machines that are getting the problem?
If my customer will allow me to send you a part of the project, should you take a look at form closing?
Thanks

Softanics
Site Admin
Posts: 1402
Joined: Sat Sep 18, 2004 3:03 am
Location: Russia, St. Petersburg
Contact:

Postby Softanics » Sat Nov 11, 2006 1:52 pm

Could you give me thread stack when the exception raises?
Best regards, Artem A. Razin,

F-IN-BOX support

Ask your question here: http://www.f-in-box.com/support.html

Silvia Tosolini
Posts: 9
Joined: Fri Sep 08, 2006 10:45 am

Postby Silvia Tosolini » Tue Nov 28, 2006 2:43 pm

Well, my customers don't allow me to send you the project code, but they can set up a VNC account in order to allow you to get direct access to the machine on which the exception raises. (on the machine there will be the visual studio solution and you'll can see the whole code).
If you agree, I'll send you privately the account information, my email address is silvia.tosolini@si2001.it.
Thank you in advance.

ovidiu
Posts: 1
Joined: Thu May 17, 2007 5:04 pm

try this..

Postby ovidiu » Thu May 17, 2007 5:07 pm

try setting a private variable on your form called closeWhenIdle, which is initially set to false. when u call the method from flash, set this variable to true and do nothing else
next, make sure that in the load event of your form u register the following event:


Application.Idle += new EventHandler(Application_Idle);

this event handler is called continuously when the application has nothing to do in terms of processing (don't worry about performance problems)

the method should look like this;


private void Application_Idle(object sender, EventArgs e)
{
if (this.CloseWhenIdle)
{
this.Close();

// useful when the OnClosing method was ovverridden
// and e.Cancel was set to true inside of it
this.CloseWhenIdle = false;
}
}

rgrant
Posts: 2
Joined: Tue Jun 23, 2009 7:46 am

Re: VB Option

Postby rgrant » Tue Jun 23, 2009 7:48 am

Do you have a solution similiar to this for Visual Basic .NET 2005? I've tried finding the Application Idle event but I haven't had any luck. Thanks

Softanics
Site Admin
Posts: 1402
Joined: Sat Sep 18, 2004 3:03 am
Location: Russia, St. Petersburg
Contact:

Re: VB Option

Postby Softanics » Tue Jun 23, 2009 8:42 am

rgrant wrote:Do you have a solution similiar to this for Visual Basic .NET 2005? I've tried finding the Application Idle event but I haven't had any luck. Thanks


Please check something like this code:

AddHandler Application.Idle, New EventHandler(AddressOf Application_Idle)
...
Private Sub Application_Idle(object sender, EventArgs e)
...


Thank you.
Best regards, Artem A. Razin,

F-IN-BOX support

Ask your question here: http://www.f-in-box.com/support.html


Return to “.NET Edition”

Who is online

Users browsing this forum: No registered users and 15 guests