出于某种原因,当我在后台线程中放置一个长时间运行的 Web 服务调用(无论是旧版还是 WCF 都无关紧要)时,它似乎锁定了 UI 主线程。
我看不出我输入的代码有什么问题。
workerThreadInitialNotify = new BackgroundWorker();
workerThreadInitialNotify.WorkerSupportsCancellation = true;
workerThreadInitialNotify.DoWork += new DoWorkEventHandler(workerThreadInitialNotify_DoWork);
workerThreadInitialNotify.RunWorkerCompleted += new RunWorkerCompletedEventHandler(workerThreadInitialNotify_RunWorkerCompleted);
workerThreadInitialNotify.RunWorkerAsync();
然后在我的工作中,我有一个网络服务调用,例如:
void workerThreadInitialNotify_DoWork(object sender, DoWorkEventArgs e)
{
if (!(sender as BackgroundWorker).CancellationPending)
{
try
{
TestWebService service = new TestWebService();
service.RunLongRunningMethod();
}
catch(Exception ex)
{
}
}
}
当这个线程被调用时,它偶尔会锁定 UI 线程,现在我已经设置 RunLongRunningMethod 故意运行缓慢和超时(出于测试目的),但从技术上讲,这根本不应该锁定 UI 线程,因为它在一个单独的线程中.
以下是该方法包含的内容:
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["customConnection"].ConnectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand("TestDelay", conn))
{
cmd.CommandType = CommandType.StoredProcedure;
try
{
cmd.ExecuteNonQuery();
}
catch (Exception ee)
{
}
}
}
和 TestDelay 存储过程只包含这个来模拟延迟,以便 Web 服务超时:
ALTER PROCEDURE [dbo].[TestDelay]
AS
WAITFOR DELAY '00:05:20';
奇怪的是,如果我用Thread.Sleep(20000);
dowork 中的 a 替换 web 服务调用,它运行得很好,或者即使我放了一个长时间运行的 while 循环,它也运行得很好。
我不知道为什么 web 服务专门让它锁定 UI。
ps:如果我将webservice设置为本地托管到Win Forms应用程序,它运行正常,只有当webservice在另一个服务上运行时,才会发生奇怪的锁定。
ps(2):我正在使用devexpress库进行表单的ui控件,而后台线程在后台运行,不确定这是否相关。我无法想象为什么,如果这是在单独的线程中正确运行