GUIALLOWED False for .net events e.g System.io.Filesystemwatcher.

GoonieGoonie Member Posts: 7
Hi
I Previously asked a related question but I am now able to boil it down to a very simple example.
Se original quesion here: http://forum.mibuso.com/discussion/67448/net-event-handling-server-client-callback-error-when-opening-page-41-42#latest

So to keep things simpler, I have taken the liberty and created a new question.

If I listen to a .net event . e.g and for simplicity - when changes to a file occur i a folder. The fired event will never allow interaction with the GUI. And I would like to know, if I somehow can achieve this !?

To reproduce:
  1. Create a codeunit (and run it in a context where the object doesn't go out of scope before tests can be done)
  2. Create a dotnet variable of type System.io.filesystemwatcher (set withevents to true)
  3. check what GUIALLOWED return on e.g. the oncreated event.

Here is sample code:
Documentation()

OnRun()
MyFileWatcher := MyFileWatcher.FileSystemWatcher();
MyFileWatcher.Path := 'C:\WatchThis';
MyFileWatcher.EnableRaisingEvents := TRUE;
MESSAGE('Ready to test');

LOCAL TriggerThis(inputMsg : Text)
MESSAGE(inputMsg);
IF(GUIALLOWED) THEN
  MESSAGE('GUI allowed')
ELSE
  MESSAGE('GUI not allowed')

MyFileWatcher::Changed(sender : Variant;e : DotNet "System.IO.FileSystemEventArgs")
TriggerThis(e.FullPath);

MyFileWatcher::Created(sender : Variant;e : DotNet "System.IO.FileSystemEventArgs")
TriggerThis(e.FullPath);

MyFileWatcher::Deleted(sender : Variant;e : DotNet "System.IO.FileSystemEventArgs")
TriggerThis(e.FullPath);

MyFileWatcher::Error(sender : Variant;e : DotNet "System.IO.ErrorEventArgs")
TriggerThis(e.ToString());

MyFileWatcher::Renamed(sender : Variant;e : DotNet "System.IO.RenamedEventArgs")
TriggerThis(e.FullPath);

MyFileWatcher::Disposed(sender : Variant;e : DotNet "System.EventArgs")
TriggerThis(e.ToString());

Best regards
Søren Lund

Answers

  • mdPartnerNLmdPartnerNL Member Posts: 802
    link does not work,

    what does not work in this situation?
  • lyngelynge Member Posts: 85
    To my knowledge this is expected behavior of the NAV client.

    The client and server does not keep a "pipe open" for communication when a object exit, it is sort of a simple webpage - you render the content and the next action is performed when somebody clicks something or the page refreshes.
    So your codeunit will exit with a 'Ready to test' and nothing happens after that. All variables including your file watcher dotnet is freed when the codeunit exits.

    Event messages like the "Ready to test" is buffered until the object exists, another dialog is opened (i.e. confirm) or a few other events happens (you can try that by calling message, delaying for 30 seconds and then calling message again. You'll find that the delay is done before showing any of the messages).

    A way to make your code work (just as a simple draft pseudo code would be):
    1. start a background job which will never exit where the file system triggers are fired and recorded to a table. You need to make this one call itself.
    2. create a page which auto-refreshes at some interval (use the ping-pong control add-in), reads the table and shows the messages accordingly.

    I not 100% sure, but a better implementation might be to define the triggers which record events to a table in a single-instance codeunit which you then declare from your page. Such a codeunit will keep its global variables on the service tier (until that one is restartet) if i remember it correctly...
  • GoonieGoonie Member Posts: 7
    Thanks @lynge . I will have a closer look at your suggestions. I can also confirm, that if i just run the codeunit, the filesystemwatchers dispose is called immediately.

    In nav 2009 I had a colleague doing the C/AL part, so I don't know how i achieved this. But in nav 2009 we had a codeunit that listened for COM events (making the .net assembly com visible). This codeunit would listen for events and create orders or quotes based on events raised by a webservice. And this is what I'm trying to port to nav 2013 / 2016.

    I know that I can create orders using nav's soap services. But i would like to change context to those orders once they are created. (Could this perhaps be done with triggers of some sort) ... I am very new to NAV and C/AL ... But learning fast :)

    If its not possible to have a codeunit running, that has implemented a .net assembly with events, as long as a nav client is running. Then one of @lynge 's option seems to be the best approach :)

    Thanks again
    Søren
Sign In or Register to comment.