- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有以下应用程序结构:
public partial class MainWindow : Window
{
// Methos to update the TextBlock
public void updateTextBlock(string txt)
{
this.myTextBlock.Text += txt;
}
private void startThreadBtn_Click(object sender, RoutedEventArgs e)
{
// Start Thread1 here
Thread1 thread1 = new Thread1();
new Thread(new ThreadStart(thread1.doSomthing)).Start();
}
}
class Thread1
{
public void doSomthing()
{
// ------------------------------
// Update myTextBlock from here
// ------------------------------
// Thread2 starts here
Thread2 thread2 = new Thread2();
new Thread(new ThreadStart(thread2.doSomthing)).Start();
}
}
class Thread2
{
public void doSomthing()
{
// ------------------------------
// Update myTextBlock from here
// ------------------------------
}
}
我想从这两个线程 Thread1
和 Thread2
类中更新 MainWindow
中的 TextBlock
>。
我已经看到了以下解决方案,并没有发现这个问题涵盖了这种情况,而且我是初学者并且发现它很难理解。
我可以使用上述问题中为 Thread1
提供的解决方案,但是如何从 Thread2
更新 UI。
我正在使用 .NET Framework 4.5。
最好的方法是什么。
最佳答案
…thread within a thread…
看来您对什么是线程有一些误解。让我们看看这些:
线程不在彼此“内部”执行。它们不是嵌套的。将线程视为“并行”执行更为准确。
第二个线程的启动方式和位置并不重要。它只是一个线程,就像你的第一个线程,所以当你想从其中一个(非 UI)线程中更新 UI 时,你在两种情况下做完全相同的事情:在 UI 线程上安排你的 UI 更新代码,这是在 WPF 中通过 Dispatcher.Invoke
或 Dispatcher.InvokeAsync
方法完成的。
myTextBlock.Dispatcher.Invoke(() => { … /* update myTextBlock here */ });
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// this will be scheduled on the correct (UI) thread
线程与您的Thread1
和Thread2
对象不同。将线程视为代表代码的执行路径;或者如果您愿意,可以自行执行的方法。线程有一个入口点(一种方法,由 ThreadStart
委托(delegate)表示),这是它的执行开始的地方,线程在到达该线程的末尾时终止。
class Thread1
{
… void doSomthing()
{
…
Thread2 thread2 = new Thread2();
new Thread(new ThreadStart(thread2.doSomthing)).Start();
}
}
即使您将类命名为 Thread1
和 Thread2
,也不会使它们成为线程。它们是常规的 .NET 类,恰好包含用作线程入口点的方法。线程仅由 Thread
类表示(请注意,您的类没有也不可能继承自 Thread
)。再说一次,你在哪里碰巧 .Start()
它们并不重要;它们彼此独立。
当你有这样的事情时:
class A { … }
class B { void Foo() { var a = new A(); … }
B
只参与 A
实例的创建位置和时间 ,但它不决定“位置” A
是。 (无论如何,类并没有真正的位置。)所以说“A
is within B
”是错误的。 (类型 A
被 B
的方法引用,a
引用一个对象实例在执行 B
的实例方法时创建,但它仍然完全独立于 B
。)
更新:关于您在下面添加的有关如何使线程知道 myTextBlock
的问题,有两种解决方案:
要么将两个 doSomthing
方法移动到 MainWindow
类中(并为它们指定唯一的名称)。
将 myTextBlock
传递给您的 Thread1
和 Thread2
对象:
class Thread1
{
public Thread1(TextBlock textBlockToBeUpdated)
{
this.textBlock = textBlock;
}
private readonly TextBlock textBlock;
void doSomthing()
{
textBlock.Dispatcher.Invoke(() => { /* update textBlock here */ });
}
}
…
class MainWindow
{
… void startThreadBtn_Click(…)
{
Thread1 thread1 = new Thread1(myTextBlock); // <--
…
}
}
关于c# - 从后台线程和线程内的线程更新 UI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26293506/
我是一名优秀的程序员,十分优秀!