在开始下一种方法之前,什么时候应该关心完成一种方法?
在 WPF 中使用 C#,结合 LINQ to SQL 和 LINQ 来查询我的通用集合,我注意到有时,当我一个接一个地使用多个方法并且下一个函数需要第一个方法的结果时,我应该关心完成以下操作:在开始下一个功能之前先执行第一个功能。
SomeMethod()
{
FirstMethod();
NextMethod();
....
}
大多数情况下,它与方法、查询数据库、下一个方法使用更新的结果有关。
是否可以总结一下c#中什么时候会出现“尚未更新继续”的可能性以及这个问题一般是如何解决的?
Using C# in WPF, together with LINQ to SQL and LINQ for quering my generic collections, I noticed that sometimes, when I use several methods one after another and results of the first one are needed for next function, I should care about finishing actions of first function before starting next.
SomeMethod()
{
FirstMethod();
NextMethod();
....
}
Mostly it is related to methods, quering database, when updated results are used by next method.
Is it possible to sum up when the possibility of "not yet updated for continuing" can take place in c# and how this issue is generally solved?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
除非您正在进行多线程处理,否则通常不难避免在准备好之前继续的情况。在大多数情况下,当您调用方法或请求数据时,只有前一条指令完成或至少准备就绪后,才会执行下一条指令。
(例如,您可以开始使用DataReader,它会在获得所有数据之前将控制权返回给您的代码,但它仍然可以保护您免于“超前”。它不会给您如果您使用它的速度比获取数据的速度快,它将迫使您等待下一条指令,而不是弄乱您的逻辑,并且如果您没有定义 Linq 表达式。实际上,当您要求其结果时,它总是会及时执行。)
.Net 可以很好地保护您免受异步问题的影响,除非您要求它们。如果您使用多线程,或者在其他地方触发外部进程(网络服务或其他东西),然后假设立即完成并且你可以依赖它的结果,那么你就会遇到问题。但一般来说,只需编写代码即可。
有时处理异步问题对我来说很棘手,但它们从来没有真正让我感到惊讶。
Unless you're doing multi-threading, it usually is not too hard to avoid the situation where you continue before you're ready. In most situations where you call a method or ask for data, your next instruction is not executed until the previous instruction is done or at least ready.
(For example, you can start using a DataReader it will return control to your code before it has all the data, but it still protects you from "getting ahead of yourself". it won't give you a false "end". If you use it faster than it gets the data, it will force your next instruction to wait rather than mess up your logic. And if you're defined Linq expression hasn't actually executed yet, it always will, in time, when you ask for its results.)
.Net protects you pretty well from asynchronous problems, unless you ask for them. If you're multi-threading, or triggering an external process (web service or something) somewhere else and then assuming instantly that it's finished and you can depend on its outcome, then you'll have problems. But in general, just code away.
It has sometimes been tricky for me dealing with asynchronous issues, but they have never really taken me by surprise.
仅当您调用的函数是异步或“非阻塞”(这是不常见的)时,这才应该成为问题。只需检查该函数的文档即可。如果您显式使用一个或多个线程,请使用联接来确保它们完成执行。如果您使用的函数名称以“Begin”开头,请从相应的 End 处调用下一个操作。最后的手段是使用循环和 Thread.Sleep(0);强制执行等待某个条件成立。
This should only be an issue if a function you are calling is asynchronous or "non-blocking," which is unusual. Just check the documentation of the function. If you are explicitly using a thread or threads, use a join to ensure they finish execution. If you are using a function whose name starts with "Begin," call the next operation from the corresponding End. The last resort is using a loop and a Thread.Sleep(0); to force execution to wait for a certain condition to be true.
您始终需要注意代码中的“副作用”和“决定论”。如果副作用(即代码运行时发生的情况)可能对其他事情(插入、删除行、创建对象等)产生影响,您需要了解完成的顺序并在其发生时进行控制。
您还需要了解代码的确定性(即我是否可以知道当我需要它时这个东西就会在那里),同样,如果有问题,您需要控制代码的执行方式。
以处理数据库中的记录为例。您必须拥有这些记录才能对其进行处理,因此您必须按该顺序进行处理。如果两个进程位于代码中的不同位置(线程、回调、事件等)。第二个函数(处理记录)必须了解第一个函数(获取行)的状态,通常使用标志、锁、信号量等来完成。
为了确定性,请考虑函数中的保护语句。如果我的函数需要有一个字符串和一个非空对象,我首先在进入函数时检查这些条件,然后再开始调用这些对象上的方法(调用 string.ToLower() 在字符串上很好,但在 null 上则不好)目的)。通过这种方式,我正在执行运行时确定性以防止代码中出现错误(例如 NullReference 等)。编译器执行自己的编译时确定性,但它无法知道执行期间对象的状态,因此它只对操作进行比较(无论它们在语义上是否有效)。
You always need to be aware of "side-effects" and "determinism" in your code. If the side-effect (i.e. what happens when the code runs) can have an impact on something else (inserting, deleting rows, creating objects, etc) you need to be aware of the order of completion and control when it happens.
You also need to be aware of the determinism of your code (i.e. can I know that this thing will be there when I need it), again if its in question you need to control how your code executes.
Take for example processing records from a database. You must have the records before you can process them, so you must do them in that order. If the two processes are in different locations in your code (threads, callbacks, events, etc). The second function (processing the records) must be made aware of the state of the first function (getting the rows) usually done with flags, locks, semaphores, etc.
For determinism think of guard statements in a function. If my function needs to have a string and a not null object, I first check those conditions when we enter the function before I start calling methods on those objects (calling string.ToLower() is fine on a string, but bad on a null object). In this way I am doing runtime determinism to prevent errors in my code (such as NullReference, etc). The compiler performs its own compile time determinism, but it cannot be aware of the state of objects during execution so it only does its comparisons on operations (whether they are semantically valid or not).
通常
NextMethod()
将在FirstMethod()
返回后立即执行。但是,当您谈论 WCF 时,您可能正在使用异步方法,尽管通常它们的名称中应包含
Async
,即GetMonstersAsync(...)
。在这种情况下,这些方法确实会几乎同时执行。
异步方法的返回值在回调方法中处理。如果需要按顺序执行它们,则可以将对第二个方法的调用放在第一个方法的回调中。
Normally
NextMethod()
will execute just afterFirstMethod()
returns.However, as you're talking about WCF, it might be you are using asynchronous methods, although usually they should have
Async
in their name, i.e.GetMonstersAsync(...)
.In that case the methods indeed would be executed almost simultaneously.
Return values of asynchronous methods are handled in callback methods. You would place the call to the second method in the callback of the first one if you need to execute them in sequential order.
有两种方法可以解决此问题:
使用锁定机制或重新设计方法以相互馈送,强制其中一个先执行。
锁定机制可以锁定线程直到工作进程完成,也可以使用带有 while 循环的布尔值:
重构代码将涉及将一个方法的值传递到另一个方法:
为了强制 FirstMethod 完成。
There's two ways of solving this:
Use a lock mechanism or redesign your methods to feed into each other, forcing one to execute first.
A lock mechanism can either be locking the thread until a worker process completes, or using a boolean value with a while loop:
Refactoring your code would involve passing the value of one method into another method:
In order to force FirstMethod to finish.