如何使用Asyncio和GUI读取文件。

时间:2017-11-08 15:57:49

标签: python python-asyncio

我有一个文本文件,其名称解析为逗号,如下所示:

Ann Marie,Smith,ams@companyname.com

该列表中可能包含超过100个名称。我遗漏了生成所有其他GUI组件的代码,专注于加载组合框和项目。

问题:

如何在不阻止主线程加载其他GUI组件的情况下实现asyncio来读取文本文件。

这是我能想到的最好的:

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() 

1 个答案:

答案 0 :(得分:1)

此功能

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实际上是异步的,其他操作可以在读取文件时运行。当您想要将一些阻塞任务应用于异步框架时,这是一个标准过程。