让 C# 函数在返回之前等待 UI 加载

发布于 2024-11-05 13:09:05 字数 462 浏览 3 评论 0原文

我正在尝试编写一个函数,该函数将动态创建选项卡页面,填充选项卡,然后返回有关其所做操作的数据。有些事件会告诉我每个选项卡何时完成,这样我就可以知道它们何时全部加载。

所有工作都与 UI 相关,我的理解是 UI 的事情必须在主线程中发生,所以听起来我不能只创建一个线程来执行此操作,然后在我的函数中等待它。我是否误解了 UI 内容必须位于主线程上的问题?如何让我的函数等待而不阻塞 UI 中必须发生的工作?

编辑:为了澄清,选项卡页具有网络浏览器控件,它将加载各种网页,因此这些需要一些时间,并且在加载每个网页时我都会收到一个 DocumentCompleted 事件。这个想法是这样的:调用者递给我一个 url 列表。我弹出一个表单并创建一个选项卡页,其中包含每个 url 的 Web 浏览器控件,并在每个选项卡中加载一个 url。这些将在不同的时间完成,每次加载页面时都会触发 DocumentComplete 事件处理程序。当它们全部加载后,我想将数据列表返回给原始调用者。

I'm trying to write a function that will dynamically create tab pages, populate the tabs, and then return data regarding what it has done. There are events that will tell me when each tab is done, so I'll be able to tell when they're all loaded.

All the work is UI-related, and my understanding is that UI stuff has to happen in the main thread, so it sounds like I can't just create a thread to do this and then wait on it in my function. Am I misunderstanding the issue with UI stuff having to be on the main thread? How can I have my function wait without blocking the work that has to happen in the UI?

EDIT: To clarify, the tab pages have webbrowser controls which will load various web pages, so those take some amount of time and I get a DocumentCompleted event for each when it's loaded. The idea is this: The caller hands me a list of urls. I pop up a form and create a tab page containing a web browser control for each url, and load one url in each tab. These will complete at different times, each firing a DocumentComplete event handler when a page has loaded. When they've all loaded, I want to return a list of data to the original caller.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

别忘他 2024-11-12 13:09:05

...我的理解是 UI 内容必须在主线程中发生...

不,这不一定是真的。如果您想修改(比方说)后台线程中的标签,您可以执行以下操作:

MethodInvoker m = () => { label1.Text = "Another text"; };
if (InvokeRequired) {
    BeginInvoke(m);
}
else {
    m.Invoke();
}

而不是:

label1.Text = "Another text";

如果您仔细处理,则不会遇到任何跨线程问题。

编辑:
看看我在问题中提供的答案 聊天的客户端编码错误application 如果你想重构一点代码。

编辑2:
根据您的编辑,我将这样做:

  1. 从用户接收网址
  2. 启动每个浏览器和一个变量,该变量将保存您打开的选项卡数量。
  3. 启动进度条或告诉用户应用程序正在运行的东西...
  4. 每次收到 DocumentComplete 事件时,都会减少变量。
    如果变量的值为0,则所有页面均已加载。
  5. 停止进度条
  6. 将想要的数据返回给用户。

现在..什么时候需要使用Invoke每次您想要从后台线程访问某些 UI 控件时。在这种情况下,当你停止进度条时......

...and my understanding is that UI stuff has to happen in the main thread...

No, that's not necessarily true. If you want to modify, let's say, a label from a background thread, you can do:

MethodInvoker m = () => { label1.Text = "Another text"; };
if (InvokeRequired) {
    BeginInvoke(m);
}
else {
    m.Invoke();
}

instead of:

label1.Text = "Another text";

If you are carefully with that, you won't have any cross-thread problems.

Edit:
Take a look at the answer I provided in the question Client Coding error for chatting application if you want to refactor a little bit that code.

Edit 2:
According to your edit, this is how I would do that:

  1. Receive the urls from the user
  2. Start each browser and a variable that will hold how many tabs you opened.
  3. Start a progressbar or something that tells the user the application is working...
  4. Everytime you receive a DocumentComplete event, you decrease the variable.
    If the value of the variable is 0, then all pages were loaded.
  5. Stop progress bar
  6. Return the data you want to the user.

Now.. when will you need to use the Invoke? Everytime you want to access to some UI control from the background thread. In that case, when you're stopping the progress bar...

ˇ宁静的妩媚 2024-11-12 13:09:05

我不确定我是否理解正确。无论如何,看看这个:

如何从C# 中的另一个线程?

I am not sure I've got you right. Anyway, take a look at this:

How to update the GUI from another thread in C#?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文