在WPF中使用C#,与LINQ to SQL和LINQ一起查询我的泛型集合,我注意到有时候,当我一个接一个地使用多个方法并且下一个函数需要第一个的结果时,我应该关心在下一个开始之前完成第一个功能的动作。
SomeMethod()
{
FirstMethod();
NextMethod();
....
}
当下一个方法使用更新结果时,它主要与方法,查询数据库有关。
是否可以总结何时可以在c#中发生“尚未更新以继续”的可能性以及该问题通常如何解决?
答案 0 :(得分:4)
除非您正在进行多线程,否则通常不难避免在您准备好之前继续进行的情况。在大多数调用方法或请求数据的情况下,在上一条指令完成或至少准备就绪之前,不会执行下一条指令。
(例如,您可以开始使用 DataReader ,它会在拥有所有数据之前将控制权返回给您的代码,但它仍然可以保护您免于“超越自己”。它赢了给你一个错误的“结束”。如果你使用它比获取数据更快,它将迫使你的下一条指令等待而不是弄乱你的逻辑。如果你定义了 Linq表达还没有真正执行,它总是会及时地,当你要求它的结果时。)
.Net可以很好地保护您免受异步问题的影响,除非您要求它们。如果您多线程,或在其他地方触发外部流程(网络服务或其他内容),然后立即假设它已完成,你可以依靠它的结果,然后你就会遇到问题。但总的来说,只需编码即可。
我处理异步问题有时候很棘手,但它们从来没有让我感到意外。
答案 1 :(得分:2)
如果您调用的函数是异步或“非阻塞”,这应该只是一个问题,这是不常见的。只需查看该功能的文档。如果您明确使用一个或多个线程,请使用连接以确保它们完成执行。如果您使用名称以“Begin”开头的函数,请从相应的End调用下一个操作。最后一种方法是使用循环和Thread.Sleep(0);强制执行等待某个条件成立。
答案 2 :(得分:2)
您始终需要了解代码中的“副作用”和“确定性”。如果副作用(即代码运行时发生的事情)可能对其他内容产生影响(插入,删除行,创建对象等),则需要了解完成顺序和控制何时发生。
你还需要了解你的代码的确定性(即我可以知道,当我需要它时,这个东西会存在),如果它有问题你需要控制代码的执行方式。
以数据库中的处理记录为例。您必须拥有记录才能处理它们,因此您必须按顺序执行这些记录。如果这两个进程位于代码中的不同位置(线程,回调,事件等)。第二个函数(处理记录)必须知道通常用标志,锁,信号量等完成的第一个函数(获取行)的状态。
对于确定性,请考虑函数中的保护语句。如果我的函数需要一个字符串和一个非null对象,我首先检查那些条件,然后我开始调用这些对象上的方法之前进入函数(调用string.ToLower()对字符串是好的,但是对于null来说是坏的宾语)。通过这种方式,我正在进行运行时确定性以防止我的代码中的错误(例如NullReference等)。编译器执行自己的编译时确定性,但它在执行期间无法知道对象的状态,因此它只对操作进行比较(无论它们是否在语义上有效)。
答案 3 :(得分:2)
通常NextMethod()
会在FirstMethod()
返回后执行。
但是,当您谈论WCF时,可能是您正在使用异步方法,尽管通常他们的名称中应该有Async
,即GetMonstersAsync(...)
。
在这种情况下,方法确实几乎可以同时执行。
异步方法的返回值在回调方法中处理。如果需要按顺序执行,则可以在第一个方法的回调中调用第二个方法。
答案 4 :(得分:1)
有两种方法可以解决这个问题:
使用锁定机制或重新设计您的方法以相互馈送,强制首先执行。
锁机制可以锁定线程直到工作进程完成,或者使用带有while循环的布尔值:
while (locked)
{
// sleep or do something else
}
... rest of code
重构代码会涉及将一个方法的值传递给另一个方法:
NextMethod(FirstMethod());
为了强制FirstMethod完成。