我正在开发一个通过存储过程与数据库交互的应用程序。为了防止GUI无响应,我在不同的线程中运行每个存储过程。我在一个线程中用循环测试了这个,但是当我调用一个必须返回很多记录的存储过程时,GUI仍然是阻塞的。
现在我的问题是:当方法调用(本例中的存储过程)尚未完成时,是否可以进行上下文切换?我知道c#代码被编译为IL。 IL-instruction是否可能获得所有线程资源而不是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;
}
答案 0 :(得分:1)
可以在a时发生上下文切换 方法调用(存储过程) 这个案子)还没完呢?
是。上下文切换一直发生,并且比您想象的更频繁。
是否有可能是IL指令 获得所有线程资源 而不是GUI线程?
从技术上讲,您的IL代码已转换为本机代码,这是您的CPU执行的代码。指令不能“获取所有线程资源”。你的CPU只是不断执行代码,它不知道线程,进程等。它是以这种方式组织事物的操作系统,负责依次运行这些线程的特定时间片。
当上下文切换到时 另一个过程?
上下文切换通常发生在线程之间。进程没有运行,它们的线程接收执行时间。上下文切换可以随时发生 - 当线程的时间片结束时,它进入休眠状态等待某事,有中断并且需要执行中断处理程序。
与上下文切换不同 到属于的不同线程 同样的过程
就像我说线程之间发生上下文切换一样。要执行的下一个线程可能来自您的进程或其他进程。
我的猜测是你从GUI线程等待异步操作(执行SP的第二个线程)以某种方式完成 - 你阻止。你可以在GUI线程上完成SP执行 - 结果是一样的。解决方案是让您的第二个线程在完成后调用GUI线程。
例如,BackgroundWorker为此提供了一个特殊事件(RunWorkerComplete)。否则,您可以使用Control.Invoke / BeginInvoke或SynchronizationContext.Post/Send来完成。
答案 1 :(得分:0)
您的代码将始终在某个描述的方法调用中,即使该方法是您的应用程序的入口点,所以是的,显然在执行方法期间发生了上下文切换。
我怀疑知道这对你没有多大帮助。听起来像你的UI仍然阻止数据库的结果。如果您可以发布可能有用的代码示例,或者查看有关线程和UI的介绍示例,例如http://msdn.microsoft.com/en-us/library/ywkkz4s1.aspx
答案 2 :(得分:0)
上下文切换可以在未定义为原子的所有操作上发生。在某些语言中,有一些特殊的原子功能可以保证在一个步骤中执行。这些函数通常将int赋给其他某个int或某个范围内的东西。
否则总会发生上下文切换,无法阻止这种情况。
请参阅http://msdn.microsoft.com/en-us/library/5kczs5b5(v=VS.71).aspx
上的MSDN更多信息:http://www.eggheadcafe.com/software/aspnet/32045281/atomic-operations.aspx 或http://blog.drorhelper.com/2008/09/why-atomic-operations-are-not-always.html
至于你的问题:我正朝着与forsvarir相同的方向前进,我假设你的长期运行线程直接写回Form-component。这不起作用,请使用Invoke。
HTH
马里奥