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