- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我不太确定,我的问题/错误在哪里。我将 WPF 与 MVVM 模式结合使用,我的问题出在登录上。
我的第一次尝试效果很好。我有几个窗口,每个窗口都有自己的 ViewModel。在登录 ViewModel 中,我运行了以下代码:
PanelMainMessage = "Verbindung zum Server wird aufgebaut";
PanelLoading = true;
_isValid = _isSupportUser = false;
string server = Environment.GetEnvironmentVariable("CidServer");
string domain = Environment.GetEnvironmentVariable("SMARTDomain");
try
{
using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, server + "." + domain))
{
// validate the credentials
PanelMainMessage = "username und passwort werden überprüft";
_isValid = pc.ValidateCredentials(Username, _view.PasswortBox.Password);
PanelMainMessage = "gruppe wird überprüft";
_isSupportUser = isSupport(Username, pc);
}
}
catch (Exception ex)
{
//errormanagement -> later
}
if (_isValid)
{
PanelLoading = false;
if (_isSupportUser)
_mainwindowviewmodel.switchToQuestionView(true);
else
_mainwindowviewmodel.switchToQuestionView(false);
}
else
PanelMainMessage = "Verbindung zum Server konnte nicht hergestellt werden";
该部分连接到 Active Directory 并首先检查登录是否成功,然后检查用户是否有特定的广告组(在方法 isSupport 中)
我在 View 中有一个显示,就像一个进度条。 PanelLoading 为真时有效。
到目前为止一切正常。
然后我创建了一个带有内容控件的主窗口,并将我的 View 更改为用户控件,这样我就可以交换它们。 (目的是不为每个 View 打开/创建一个新窗口)。
当我现在执行代码时,我的 GUI 会阻塞,直到上述部分被执行。我尝试了几种方法...
将代码片段移动到另一个方法中并将其作为自己的线程启动:
Thread t1 = new Thread(() => loginThread());
t1.SetApartmentState(ApartmentState.STA);
t1.Start();
当我这样做时,我收到一个错误消息,指出资源由另一个线程拥有,因此无法访问。 (调用线程无法访问此对象,因为另一个线程拥有它)
然后,尝试调用登录部分,而不是额外的线程;包含前面代码片段的登录
Application.Current.Dispatcher.Invoke((Action)(() =>
{
login();
}));
那是行不通的。至少不是我的实现方式。
之后,我尝试在一个线程中只运行登录片段的主要部分,并在完成后引发一个先前注册的事件,该事件将处理内容控件的更改。这就是我在线程访问另一个线程拥有的资源时遇到错误的部分,所以我想,我可以解决这个问题。
void HandleThreadDone(object sender, EventArgs e)
{
if (_isValid)
{
PanelLoading = false;
_mainwindowviewmodel.switchToQuestionView(_isSupportUser);
}
else
PanelMainMessage = "Verbindung zum Server konnte nicht hergestellt werden";
}
在登录方法中,我会调用 ThreadDone(this, EventArgs.Empty);完成后。好吧,关于另一个线程拥有的资源,我遇到了同样的错误。
现在我在这里,寻求帮助...
我知道我的代码不是最漂亮的,而且我至少两次破坏了 mvvm 模式背后的想法。另外我对Invoke方法了解甚少,但我尽力在stackoverflow和其他网站上搜索了一段时间(2-3小时),但没有成功。
指定线程发生错误的位置:
_mainwindowviewmodel.switchToQuestionView(_isSupportUser);
which leads to the following method
public void switchToQuestionView(bool supportUser)
{
_view.ContentHolder.Content = new SwitchPanel(supportUser);
}
这也是我没有使用数据绑定(bind)的一种情况。我更改了内容控件的内容:
<ContentControl Name="ContentHolder"/>
我将如何使用数据绑定(bind)实现这一点。该属性是否应具有 ContentControl 类型?我真的找不到答案。通过将其更改为 DataBinding,是否可以解决线程所有权的错误?
项目结构如下:主视图是入口点,在构造函数中,数据上下文设置为当时创建的主视图模型。主视图有一个内容控件,我可以在其中切换我的用户控件,在本例中是我的 View 。
在我的 mainviewmodel 中,我在 usercontrol 登录的开头设置了 contentcontrol 的内容,它在其构造函数中创建了一个 viewmodel 并将其设置为 datacontext。
代码片段来 self 的登录 View 模型。希望这会有所帮助。
我以为我找到了解决方法,但它仍然不起作用。我忘记了,计时器在后台是如何工作的,所以也可以这样解决。
最佳答案
问题是 WPF 或一般的 XAML 框架不允许从其他线程修改主线程上的可视元素。为了解决这个问题,您应该区分哪部分代码是从第二个线程更新 View 的。在你的情况下,我可以看到:
_view.ContentHolder.Content = new SwitchPanel(supportUser);
改变 View 。为了解决这个问题,你可以试试这个 answer .其中我使用同步上下文来进行线程间的通信。
解决它的另一种方法(这可能是调度程序的错误用法)是使用调度程序将修改 View 的操作“发送”到主线程。像这样的事情:
var dispatcher = Application.Current.Dispatcher;
//also could be a background worker
Thread t1 = new Thread(() =>
{
dispatcher .Invoke((Action)(() =>
{
login(); //or any action that update the view
}));
//loginThread();
});
t1.SetApartmentState(ApartmentState.STA);
t1.Start();
希望这有助于...
关于C# WPF MVVM 阻塞 UI 线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24686346/
对于一个简单的聊天程序,我使用了一个通过 boost::python 包装的 c 库。 使用 PyQT 编写了一个简单的 GUI。接收消息是通过阻塞调用完成的lib说。对于独立刷新的 GUI,通信部分
当我创建以下内容时,我试图创建一个可以被异常终止的线程类(因为我试图让线程等待一个事件): import sys class testThread(threading.Thread): def
我正在用 Haskell 编写服务器,我想在客户端断开连接后显式关闭它们。当我调用 hClose ,线程将阻塞,直到客户端关闭其一侧的句柄。有没有办法让它在不阻塞的情况下关闭? 提前致谢! 最佳答案
这个问题已经有答案了: 已关闭12 年前。 Possible Duplicate: garbage collection Operation 我有几个相关问题。 1.JAVA垃圾收集器运行时,是否占用
我有一个 Angular 函数,它在初始 URL 中查找“列表”参数,如果找到,就会出去获取信息。否则我想获得地理位置。如果存在 URL 参数,我不想获取地理位置。我使用的术语是否正确? constr
我读了很多关于锁定数据库、表和行的文章,但我想要较低的锁定,比如只锁定“操作”,我不知道如何调用它,假设我在 php 中有函数: function update_table() { //que
在我的多线程 mfc 应用程序中,m_view->SetScrollPos 处于阻塞状态并且所有应用程序都被卡住。 View 是在另一个线程中创建的,这是这种行为的原因吗? //SetScrollPo
FreeSwitch 软件在几天内运行良好(~3 - 5 天),然后由于 FreeSwitch 被阻止,新的来电请求被接受!!正在进行的调用继续他们的 session ,他们的调用似乎没有受到影响,但
我有一组按钮,当鼠标悬停在这些按钮上时,它们会改变颜色。这些的 CSS 以这种方式运行: #navsite ul li button { height: 60px; width: 60
由于某些原因,当我调用 WSARecvFrom 时,该函数在接收到某些内容之前不会返回。 _socket = WSASocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, N
我了解一些关于 Oracle 阻塞的知识——更新如何阻塞其他更新直到事务完成,写入者如何不阻塞读取者等。 我理解悲观和乐观锁定的概念,以及有关丢失更新等典型银行教科书示例。 我也理解 JDBC 事务隔
在两个代码点之间,我是否可以判断进程是否已被内核抢占,或者更确切地说,当时是否有任何其他代码在同一处理器上运行? //Point A some_type capture = some_capture(
这是我在 Oracle 的面试问题。 有一个堆栈,即使堆栈已满,push 操作也应该等到它完成,即使堆栈为空,pop 操作也应该等到它完成。 我们怎样才能做到这一点? 我的回答 让一个线程做push
我想知道是否有人可以告诉我如何有效地使用循环平铺/循环阻塞进行大型密集矩阵乘法。我正在用 1000x1000 矩阵做C = AB。我按照 Wikipedia 上的循环平铺示例进行操作,但使用平铺得到的
我正在阅读有关绿色线程的内容,并且能够理解这些线程是由 VM 或在运行时创建的,而不是由操作系统创建的,但我无法理解以下语句 When a green thread executes a blocki
我正在创建的 JavaScript API 具有以下结构: var engine = new Engine({ engineName: "TestEngine", engineHost
ChildWindow 是一个模态窗口,但它不会阻塞。有没有办法让它阻塞?我基本上想要一个 ShowDialog() 方法,该方法将调用 ChildWindow.Show() 但在用户关闭 Child
我需要一些关于如何调试 10.6 版本下的 Cocoa 并发问题的指导。我正在将“for”循环转换为使用 NSOperations,但大多数时候,代码只是在循环的某个时刻卡住。我可以在控制台中看到 N
我正在使用 ReportViewer 控件和自定义打印作业工作流程,这给我带来了一些问题。我的代码看起来有点像这样: ids.ForEach(delegate(Guid? guid)
我有以下成功复制文件的代码。但是,它有两个问题: progressBar.setValue() 之后的 System.out.println() 不会打印 0 到 100 之间的间隔(仅打印“0”直到
我是一名优秀的程序员,十分优秀!