System.Io.Directory::GetFiles () Poll since AX 2009, only view new files Every 10 seconds

I wrote code in AX 2009 to poll a directory on a network drive every 1 second, waiting for a file to respond from another system. I noticed that using the file explorer window, I could see that the file appeared, but my code did not see or process the file for several seconds - up to 9 seconds (and 9 polls) after the file appeared!

AX code calls System.IO.Directory::GetFiles()with ClrInterop:

interopPerm = new InteropPermission(InteropKind::ClrInterop);
interopPerm.assert();
files = System.IO.Directory::GetFiles(#POLLDIR,'*.csv');
// etc...
CodeAccessPermission::revertAssert();

After long experiments, it turned out that for the first time in my life program, the program that I call ::GetFiles(), it starts the conditional "ticking clock" with a period of 10 seconds. Only every 10 seconds calls all new files that may have appeared, although they still report files found in an earlier 10-second tick from the first call ::GetFiles().

If there is no file when starting the program, all other calls ::GetFiles(), 1 second after the first call, 2 seconds, etc., up to 9 seconds after that, just do not see the file, although it may have sat there from 0, 5 seconds after the first call!

, , 10 . 11 19 , , 20 . , 10 .

, AX AOS-, , , , , .

10s , , , , .

, , 10- ; , .

?

+4
3

, DAXaholic , , EnumerateFiles.

, . FileSystemWatcher, , . , - . .

+1

, SMB - :

,
[DWORD] DirectoryCacheLifetime

: HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Lanmanworkstation\Parameters

, . , . , , , , . , , - , // .


HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Lanmanworkstation\Parameters\DirectoryCacheLifetime

to 0

+2

Thanks to @Jan B. Kjeldsen, I was able to solve my problem using FileSystemWatcher. Here is my implementation in X ++:

class SelTestThreadDirPolling
{
}

public server static Container SetStaticFileWatcher(str _dirPath,str _filenamePattern,int _timeoutMs)
{
    InteropPermission interopPerm;
    System.IO.FileSystemWatcher fw;
    System.IO.WatcherChangeTypes watcherChangeType;
    System.IO.WaitForChangedResult res;
    Container cont;
    str fileName;
    str oldFileName;
    str changeType;
    ;

    interopPerm = new InteropPermission(InteropKind::ClrInterop);
    interopPerm.assert();
    fw = new System.IO.FileSystemWatcher();
    fw.set_Path(_dirPath);
    fw.set_IncludeSubdirectories(false);
    fw.set_Filter(_filenamePattern);

    watcherChangeType = ClrInterop::parseClrEnum('System.IO.WatcherChangeTypes', 'Created');
    res = fw.WaitForChanged(watcherChangeType,_timeoutMs);
    if (res.get_TimedOut()) return conNull();

    fileName = res.get_Name();
    //ChangeTypeName can be: Created, Deleted, Renamed and Changed
    changeType = System.Enum::GetName(watcherChangeType.GetType(), res.get_ChangeType());

    fw.Dispose();
    CodeAccessPermission::revertAssert();

    if (changeType == 'Renamed') oldFileName = res.get_OldName();

    cont += fileName;
    cont += changeType;
    cont += oldFileName;
    return cont;
}

void waitFileSystemWatcher(str _dirPath,str _filenamePattern,int _timeoutMs)
{
    container cResult;
    str filename,changeType,oldFilename;
    ;

    cResult=SelTestThreadDirPolling::SetStaticFileWatcher(_dirPath,_filenamePattern,_timeoutMs);
    if (cResult)
    {
        [filename,changeType,oldFilename]=cResult;
        info(strfmt("filename=%1, changeType=%2, oldFilename=%3",filename,changeType,oldFilename));
    }
    else
    {
        info("TIMED OUT");
    }
}

void run()
{;
    this.waitFileSystemWatcher(@'\\myserver\mydir','filepattern*.csv',10000);
}

I must admit the following to form the basis of my X ++ implementation:

https://blogs.msdn.microsoft.com/floditt/2008/09/01/how-to-implement-filesystemwatcher-with-x/

+2
source

Source: https://habr.com/ru/post/1669961/


All Articles