C# 不同的线程在WPF中拥有它
这是我正在使用的C# 不同的线程在WPF中拥有它,c#,.net,wpf,multithreading,dispatcher,C#,.net,Wpf,Multithreading,Dispatcher,这是我正在使用的UserControl this.cardename.Content是一个标签,位于用户控件的UI中 public partial class PersonCredential : UserControl { public PersonCredential() { InitializeComponent(); Dispatcher.BeginInvok
UserControl
this.cardename.Content是一个标签,位于用户控件的UI中
public partial class PersonCredential : UserControl
{
public PersonCredential()
{
InitializeComponent();
Dispatcher.BeginInvoke( (Action) (() => {
SCLib type = new SCLib();
type.StartMonitoring();
type.CardArrived += (string ATR) => { this.CardHolderName.Content = ATR; };
};
}));
我仍然收到错误,“调用线程无法访问此对象,因为另一个线程拥有它”,即使我正在使用Dispatcher.BeginInvoke
调度器的使用方式是否有问题?
}
编辑:
我正在内容控件中实例化该用户控件,其背后的代码是:
public partial class MainWindow : Window
{
PersonCredential personCredential {get;set;}
public MainWindow()
{
InitializeComponent();
var personCredential = new CoffeeShop.PersonCredential();
//create an instance of user control.
this.personCredentials.Content = personCredential;
// assign it to the content control inside the wpf main window
.. // blah blah
}
编辑1:
启动监控代码:
public async void StartMonitoring()
{
// Wait for user to press a key
try
{
this.establishContext();
await Task.Run(new Action(WaitForReaderArrival));
////WaitForReaderArrival();
if (IsReaderArrived())
编辑@DanPuzey的评论<代码>开始监视
已在另一个线程上监视。关键是没有从UI线程引发cardarived
事件:
public PersonCredential()
{
InitializeComponent();
SCLib type = new SCLib();
type.StartMonitoring();
type.CardArrived += (string ATR) => {
// when card arrives, dispatch back to UI thread
Dispatcher.BeginInvoke(new Action(() => {
this.CardHolderName.Content = ATR;
}));
};
}
如果您使用的是.NET 4或更高版本,请使用而不是new Thread()
如果IsReaderArrived
检查是一个即时非阻塞调用(即完成不到50毫秒),我建议使用Task.Delay(interval)
在调用方线程上启动轮询循环:
这是一个异步循环。如果从UI线程调用StartMonitoring
,则将在同一UI线程上触发CardArrived
事件,并且代码的客户端不必担心Dispatcher.BeginInvoke
。如果您需要解释这是如何发生的,read是否从后台线程调用构造函数?这本身就是一个问题。您应该在UI线程上创建所有UI内容(包括UserControl)。请发布从何处实例化此UserControl的代码。CheckAccess()
的结果可能会很有趣。@nowhewhomustnotbenamed我刚刚更新了我的答案以包含一个解释,@DanPuzey在注释中比我更清楚。事件是从另一个线程引发的-您在StartMonitoring
@中启动的线程现在他不应该被命名,我在中解释了这一点。非常感谢。如果您能告诉我为什么没有新线程的调度程序不能工作,但线程下的同一任务运行良好,那将非常有帮助。我认为不需要新线程(…).Start()
——此解决方案的重要部分是事件处理程序中的调度程序.Invoke
。通常不会从dispatcher线程调用事件处理程序,这可能是错误的来源。@DanPuzey是的,但StartMonitoring
以无限循环等待,请参阅question@DanPuzey:是的,你是对的。刚刚删除了新线程(…).Start()
并且一切都是一样的:)如果StartMonitoring()
在无限循环中等待,那么事件处理程序将永远不会被设置(代码将在到达type.CardArrived+=…
之前在无限循环中阻塞)-所以我认为你的说法不太正确。现在我明白了。非常感谢<代码>调度程序
现在似乎没有必要!
public async Task StartMonitoring(int interval, CancellationToken token)
{
this.establishContext();
while (true)
{
token.ThrowIfCancellationRequested();
if (IsReaderArrived())
{
// make sure to reset the flag inside IsReaderArrived
// so the event won't be fired upon the next iteration
if (this.CardArrived != null)
this.CardArrived(this, EventArgs.Empty);
}
await Task.Delay(interval);
}
}