C# WPF中的多线程编程
当我将浏览器控件传递给跟踪浏览器控件值的后台任务时,出现此错误。我需要在代码中做什么更改才能将此浏览器控件安全地传递给我的后台类 错误C# WPF中的多线程编程,c#,wpf,.net-4.5,C#,Wpf,.net 4.5,当我将浏览器控件传递给跟踪浏览器控件值的后台任务时,出现此错误。我需要在代码中做什么更改才能将此浏览器控件安全地传递给我的后台类 错误 The calling thread must be STA, because many UI components require this. 下面是我如何将浏览器控件传递给我的后台singleton类 public partial class MainWindow : Window { public MainWindow()
The calling thread must be STA, because many UI components require this.
下面是我如何将浏览器控件传递给我的后台singleton类
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
brwser.Navigate("https://xyz.com");
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
Task.Factory.StartNew(() =>
{
if (BfScrapper.Instance.CanStart)
BfScrapper.Instance.StartTask(brwser);
});
}
}
您必须启动运行STA线程的任务 为此,您需要使用(假设创建任务的线程本身就是STA线程) 您可以将其传递给接受TaskScheduler参数的的重载之一 例如:
Task.Factory.StartNew
(
() =>
{
if (BfScrapper.Instance.CanStart)
BfScrapper.Instance.StartTask(brwser);
},
CancellationToken.None,
TaskCreationOptions.None,
TaskScheduler.FromCurrentSynchronizationContext()
);
我还建议您使用google FromCurrentSynchronizationContext STA,因为这一点并不明显,而且会产生一些影响。我猜您正在尝试更改传递的UI元素中的某些内容。最简单的方法如下:
mLabel.DispatcherCall(() => mLabel.Text = "Test...", DispatcherPriority.Normal);
UIElement.Dispatcher.BeginInvoke(/*在这里做事*/)代码>
我有一个方便的扩展方法:
public static DispatcherOperation DispatcherCall<T>(this T obj, Action action, DispatcherPriority priority) where T : DispatcherObject
{
return obj.Dispatcher.BeginInvoke(priority, action);
}
这避免了在同步上下文之间来回切换的巨大成本请不要在标题中重复标记。其不重复的重新引用示例是不使用任务/任务工厂类启动singleton Classis的新实例。我已编辑了标题。请看“”,其中的共识是“不,他们不应该”。你能通过传递contorl来分享如何在这种情况下使用的代码片段吗?它非常有效,谢谢我希望我能给出很多分数,而不是像其他人一样参考旧答案。这是我想从像你这样的专家那里听到的答案。因为这个类使用Task Factory当我第一次开始使用任务而不是线程时,我遇到了这个问题(线程很容易修复,因为您可以为线程设置STA状态)。我花了很长时间才发现FromCurrentSynchronizationContext()的问题!但对每个人都要公平——他们都在尽力帮助(我自己也经常发布回复,结果证明没有我希望的那么有帮助……)