Python使用concurrent.futures在streamlit中出现“missing ReportContext”错误

4

我在使用concurrent.futures时,在我的streamlit应用程序中控制台收到了许多警告。

其中一些警告如下:

2020-10-28 15:43:59.338 Thread 'ThreadPoolExecutor-1_11': missing ReportContext
2020-10-28 15:43:59.338 Thread 'ThreadPoolExecutor-1_8': missing ReportContext
2020-10-28 15:43:59.339 Thread 'ThreadPoolExecutor-1_9': missing ReportContext
2020-10-28 15:43:59.339 Thread 'ThreadPoolExecutor-1_6': missing ReportContext
2020-10-28 15:43:59.339 Thread 'ThreadPoolExecutor-1_7': missing ReportContext
2020-10-28 15:43:59.340 Thread 'ThreadPoolExecutor-1_10': missing ReportContext
2020-10-28 15:43:59.340 Thread 'ThreadPoolExecutor-1_11': missing ReportContext
2020-10-28 15:43:59.341 Thread 'ThreadPoolExecutor-1_8': missing ReportContext
2020-10-28 15:43:59.341 Thread 'ThreadPoolExecutor-1_9': missing ReportContext
2020-10-28 15:43:59.342 Thread 'ThreadPoolExecutor-1_10': missing ReportContext
2020-10-28 15:43:59.342 Thread 'ThreadPoolExecutor-1_11': missing ReportContext

我知道应该使用 add_report_ctx(thread) 来创建线程。(参考链接

我想知道如何在 concurrent.futures 中使用?

以下是我的部分代码:

def thread_run(func, values):
    with ThreadPoolExecutor(max_workers=60) as executor:
        futures = [executor.submit(func, value) for value in values]
        for future in as_completed(futures):
            yield future.result()

我有同样的问题。不确定这是否是通用于concurrent.futures模块还是与Streamlit相关。 - avibrazil
1个回答

2
您收到此警告是因为您正在尝试从另一个线程向 streamlit 页面添加小部件等内容,但它不知道将它们发送到哪里。最好不要这样做,因为该函数将异步运行,可能无法按所需顺序获得您的小部件等内容。更好的解决方案是在函数中进行任何计算,返回结果,然后在主 streamlit 线程中添加小部件等内容。
但是,如果您确实希望这样做,您可以在将运行的函数中向当前线程添加报告上下文。
def func(value, ctx):
    streamlit.report_thread.add_report_ctx(threading.currentThread(), ctx)
    # rest of func

假设这个函数运行在你的主Streamlit线程上,从你的thread_run函数中获取上下文:

def thread_run(func, values):
    with ThreadPoolExecutor(max_workers=60) as executor:
        ctx = streamlit.report_thread.get_report_ctx()
        futures = [executor.submit(func, value, ctx) for value in values]
        for future in as_completed(futures):
            yield future.result()

否则,从任何地方收集它们,然后只需通过thread_run函数传递它们即可:
def thread_run(func, values, ctxs):
    with ThreadPoolExecutor(max_workers=60) as executor:
        futures = [executor.submit(func, value, ctx) for value, ctx in zip(values, ctxs)]
        for future in as_completed(futures):
            yield future.result()

那么这个 add_report_ctx() 是从哪里来的呢?这是一个 Streamlit 的函数吗?为了清晰起见,请编辑并添加完整的函数名称。 - avibrazil
感谢 @avibrazil 指出这个问题,请查看已编辑的答案。 - Pete

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接