如何使用 Asyncio 和 GUI 读取文件。
How do I use Asyncio and GUI to read a file.
我有一个文本文件,其中的名称用逗号解析,如下所示:
Ann Marie,Smith,ams@companyname.com
列表中可能有 100 多个名字。我省略了生成所有其他 GUI 组件的代码,以专注于加载组合框和项目。
问题:
如何实现 asyncio
读取文本文件而不阻塞主线程加载其他 GUI 组件。
这是我能想到的最好的:
import wx
import asyncio
class Mywin(wx.Frame):
def __init__(self, parent, title):
super(Mywin, self).__init__(parent, title=title, size=(300, 200))
self.panel = wx.Panel(self)
box = wx.BoxSizer(wx.VERTICAL)
self.eventloop()
box.Add(self.combo, 1, wx.EXPAND | wx.ALIGN_CENTER_HORIZONTAL | wx.ALL, 5)
box.AddStretchSpacer()
self.panel.SetSizer(box)
self.Centre()
self.Show()
#code to display and position GUI components left out
async def readlist(self):
filename = 'employees.txt'
empList = []
with open(filename) as f_obj:
for line in f_obj:
empList.append(line)
return empList
async def managecombobox(self, loop):
task = loop.create_task(self.readlist())
return_value = await task
self.combo = wx.ComboBox(self.panel, choices=return_value)
def eventloop(self):
event_loop = asyncio.get_event_loop()
try:
event_loop.run_until_complete(self.managecombobox(event_loop))
finally:
event_loop.close()
def OnCombo(self, event):
self.label.SetLabel("You selected" + self.combo.GetValue() + " from Combobox")
app = wx.App()
Mywin(None, 'ComboBox Demo')
app.MainLoop()
这个函数
async def readlist(self):
filename = 'employees.txt'
empList = []
with open(filename) as f_obj:
for line in f_obj:
empList.append(line)
return empList
不是异步。文件读取是同步的,发生这种情况时没有其他任务可以 运行。现在由于文件读取默认是阻塞的,所以让它异步并不容易。一种方法是将任务提交到单独的线程:
import asyncio
from concurrent.futures import ThreadPoolExecutor
FileIOPool = ThreadPoolExecutor(8) # you may pass here something like 2*CPU_CORES
class Mywin(wx.Frame):
...
def read_file(self):
filename = 'employees.txt'
empList = []
with open(filename) as f_obj:
for line in f_obj:
empList.append(line)
return empList
async def readlist(self):
loop = asyncio.get_event_loop()
return await loop.run_in_executor(FileIOPool, self.read_file)
现在 readlist
是真正的异步,其他操作可以 运行 在读取文件的同时进行。当您想将一些阻塞任务应用于异步框架时,这是一个标准过程。
我有一个文本文件,其中的名称用逗号解析,如下所示:
Ann Marie,Smith,ams@companyname.com
列表中可能有 100 多个名字。我省略了生成所有其他 GUI 组件的代码,以专注于加载组合框和项目。
问题:
如何实现 asyncio
读取文本文件而不阻塞主线程加载其他 GUI 组件。
这是我能想到的最好的:
import wx
import asyncio
class Mywin(wx.Frame):
def __init__(self, parent, title):
super(Mywin, self).__init__(parent, title=title, size=(300, 200))
self.panel = wx.Panel(self)
box = wx.BoxSizer(wx.VERTICAL)
self.eventloop()
box.Add(self.combo, 1, wx.EXPAND | wx.ALIGN_CENTER_HORIZONTAL | wx.ALL, 5)
box.AddStretchSpacer()
self.panel.SetSizer(box)
self.Centre()
self.Show()
#code to display and position GUI components left out
async def readlist(self):
filename = 'employees.txt'
empList = []
with open(filename) as f_obj:
for line in f_obj:
empList.append(line)
return empList
async def managecombobox(self, loop):
task = loop.create_task(self.readlist())
return_value = await task
self.combo = wx.ComboBox(self.panel, choices=return_value)
def eventloop(self):
event_loop = asyncio.get_event_loop()
try:
event_loop.run_until_complete(self.managecombobox(event_loop))
finally:
event_loop.close()
def OnCombo(self, event):
self.label.SetLabel("You selected" + self.combo.GetValue() + " from Combobox")
app = wx.App()
Mywin(None, 'ComboBox Demo')
app.MainLoop()
这个函数
async def readlist(self):
filename = 'employees.txt'
empList = []
with open(filename) as f_obj:
for line in f_obj:
empList.append(line)
return empList
不是异步。文件读取是同步的,发生这种情况时没有其他任务可以 运行。现在由于文件读取默认是阻塞的,所以让它异步并不容易。一种方法是将任务提交到单独的线程:
import asyncio
from concurrent.futures import ThreadPoolExecutor
FileIOPool = ThreadPoolExecutor(8) # you may pass here something like 2*CPU_CORES
class Mywin(wx.Frame):
...
def read_file(self):
filename = 'employees.txt'
empList = []
with open(filename) as f_obj:
for line in f_obj:
empList.append(line)
return empList
async def readlist(self):
loop = asyncio.get_event_loop()
return await loop.run_in_executor(FileIOPool, self.read_file)
现在 readlist
是真正的异步,其他操作可以 运行 在读取文件的同时进行。当您想将一些阻塞任务应用于异步框架时,这是一个标准过程。