在方法调用期间可以发生上下文切换吗?
本文关键字:上下文切换 方法 调用 | 更新日期: 2023-09-27 17:49:16
我正在研究一个通过存储过程与数据库交互的应用程序。为了防止GUI无响应,我在不同的线程中运行每个存储过程。我用线程中的循环测试了这一点,并且有效,但是当我调用必须返回非常多记录的存储过程时,GUI仍然阻塞。
现在我的问题是:当方法调用(本例中为存储过程)尚未完成时,是否可以发生上下文切换?我知道c#代码被编译成IL。是否有可能,一个IL指令得到所有的线程资源,而不是GUI线程?何时发生上下文切换到另一个进程,它是否与上下文切换到属于同一进程的不同线程不同?
编辑:这是我如何启动线程:
private void button2_Click(object sender, EventArgs e)
{
filldb = new Thread(adddummytodb);
filldb.Start();
}
这是调用存储过程线程中的代码。当我运行这个时,GUI直接挂起,但是我知道存储过程调用持续了一段明显的时间,因为它得到了+100000条记录。线程什么时候结束?当被调用的filldgv方法被调用或完成时?
private void adddummytodb()
{
Eigenaars = dc.sp_SearchEigenaar("", "", "", null, null);
this.dataGridView1.Invoke((controlInvoke)filldgv);
当我用一个短时间的存储过程调用循环运行这段代码时,GUI保持响应:
private void adddummytodb()
{
int ts;
for (int i = 0; i < 2000; i++)
{
if (stopthread == false)
{
ts = dc.sp_SaveCst(0);
}
else
break;
}
是否可以发生上下文切换方法调用(中的存储过程)这个案子还没办完?
是的。上下文切换一直在发生,而且比你想象的要频繁得多。
是否有可能il指令获得所有线程资源而不是GUI线程?
从技术上讲,你的IL代码被翻译成本机机器码,这是你的CPU执行。指令不能"获得所有线程资源"。你的CPU只是不断地执行代码,它不知道线程,进程等。它是操作系统以这种方式组织事物,并负责在特定的时间片依次运行这些线程。
上下文切换通常发生在线程之间。进程不是运行的,是它们的线程接收执行时间。上下文切换可以在任何时候发生——当线程的时间片结束时,它会进入睡眠状态,等待一些事情,有一个中断,需要执行一个中断处理程序。发生上下文切换到另一个进程?
就像我说的上下文切换发生在线程之间。下一个要执行的线程可能来自您的进程,也可能来自其他进程。与上下文切换有什么不同吗的不同线程同样的过程
我的猜测是,您从GUI线程等待异步操作(执行SP的第二个线程)以某种方式完成-您阻塞。您可以在GUI线程上执行SP—结果是一样的。解决方案是让第二个线程在GUI线程完成后调用它。
例如,BackgroundWorker提供了一个特殊的事件(RunWorkerComplete)。否则你可以用Control来做。调用/BeginInvoke或SynchronizationContext.Post/Send你的代码将总是在某个描述的方法调用中,即使那个方法是你的应用程序的入口点,所以是的,显然上下文切换发生在方法执行期间。
我怀疑知道这些对你没有多大帮助。这听起来像你的UI仍然阻塞从数据库的结果。如果你能发布一个代码示例,可能会有所帮助,或者看看一个关于线程和ui的介绍性示例,例如http://msdn.microsoft.com/en-us/library/ywkkz4s1.aspx
上下文切换可以发生在所有未定义为原子的操作上。在某些语言中,有一些特殊的原子函数可以保证在一步中执行。这些函数通常将一个整型赋值给另一个整型或类似的值。
否则总是会发生上下文切换,没有办法阻止它。
参见MSDN http://msdn.microsoft.com/en-us/library/5kczs5b5(v=VS.71).aspx
更多信息:http://www.eggheadcafe.com/software/aspnet/32045281/atomic-operations.aspx或http://blog.drorhelper.com/2008/09/why-atomic-operations-are-not-always.html
至于你的问题:我正朝着与forvarir相同的方向前进,我假设你的长时间运行的线程直接写回Form-component。这行不通,请使用Invoke.
hth
马里奥