Home > Net >  How to handle asynchronous file loading with events in Python
How to handle asynchronous file loading with events in Python

Time:11-19

So I am a little confused on how to use events in Python. I have an API for a program I use that recently changed its file loading method to be asynchronous. These files can take a while to load and in the past the file loading method would halt execution until the file was loaded. Now it immediately goes on to the next line but everything fails then because the file isn't actually loaded yet.

This API does provide an event that fires once the file is loaded. However, I can't wrap my head around how I would change my code to work with this new event-driven method.

Essentially I want to load the file, wait until it is actually loaded, and then continue on with the rest of the program. I was thinking it would be something like:

import API

fileLoader = API.FileLoader()

fileLoader.LoadFile('path/to/file')

while not fileLoader.OnFileLoaded():
    # do some sort of waiting here?

# continue on with the rest of the code

I have been trying to read up on decorators and callbacks and other such things but they all seem to be used mainly in GUI or web development stuff where everything is event based. This is just one step that needs to wait for an event to fire.

I also don't think the OnFileLoaded event really works like that. I don't see any return value from it and from what I can tell it takes an object called a FileLoaded object that contains data about where it was loaded into. My guess would be that you can try to load multiple files in different instances and just work with them as they get loaded in.

Is there some sort of standard pythonic way of dealing with stuff like this?

Update:

Below is what Visual Studio gives for information on the OnFileLoaded event

public event API.FileLoader.OnFileLoadedDelegate OnFileLoaded
    Member of API.FileLoader

And for the LoadFile method

public void LoadFile(string filePath)
    Member of API.FileLoader

And then I went to look what this OnFileLoadedDelegate was and I found this

public delegate void OnFileLoadedDelegate(API2.Models.FileLoaded fileLoaded)
    Member of API.FileLoader

And it had two methods, one called BeginInvoke

public virtual System.IAsyncResult BeginInvoke(API2.Models.FileLoaded fileLoaded, System.AsyncCallback callback, object object)
    Member of API.FileLoader.OnFileLoadedDelegate

and one called EndInvoke

public virtual void EndInvoke(System.IAsyncResult result)
    Member of API.FileLoader.OnFileLoadedDelegate

Finally I found one more method in the FileLoader class called GetAutomationCallbackService

protected override API2.IApplicationCallbackService GetAutomationCallbackService()
    Member of API.FileLoader

If I go to API2 I see that it also has an inteface (?) named OnFileLoaded

I hope that helps clear this up, I am quite confused how it all fits together.

CodePudding user response:

If this API is working the way I think, you would create your own class that overrides OnFileLoaded to do what you want. One option is for this class to have an Event that it sets when it gets the OnFileLoaded event.

import API
import threading

class WaitFileLoad(API.FileLoader):

    def __init__(self):
        self._event = threading.Event()
        super().__init__()

    def LoadFile(self, path):
        self._event.clear()
        super().LoadFile(path)

    def wait(self):
        self._event.wait()

    def OnFileLoaded(self, *args, **kwargs):
        print("OnFileLoaded", type(self), args, kwargs)
        self._event.set()

fileLoader = WaitFileLoad()
fileLoader.LoadFile('path/to/file')
fileLoader.wait()
# continue on with the rest of the code

CodePudding user response:

You can use something like

import asyncio

loop = asyncio.get_event_loop()
fileLoader = loop.run_until_complete(API.FileLoader())
loop.run_until_complete(fileLoader.LoadFile('path/to/file'))

to be sure that you will load the file before the code pass to the next line

  • Related