抱歉无法发布任何代码示例(我还没有能够提炼成一个小的,可重现的代码库,而且我拥有的代码是专有的。)
我的情况是这样的:我有一个使用Excel DNA开发的Excel加载项,它从需要身份验证的REST Web服务中提取数据。加载项按会话存储凭据,但不会在Excel实例之间保留。还存在一个向用户公开的宏,允许他们调用加载项中的代码以从Web服务中提取数据。
问题在于,如果用户之前没有登录,我们会弹出一个Windows窗体对话框,要求提供凭据。这很好用。成功登录后,我们的逻辑开始(在一次测试中,有6个并发请求)从Web服务中提取数据。有一点来回(请求数据,未经授权,登录,再次请求,提取数据等)。如果登录以编程方式发生(没有呈现或实例化Windows窗体),一切正常。
我看到的问题是,当涉及Windows窗体时,我看到授权请求和获取数据之间的1分29秒延迟(加/减几分之一秒)。这种延迟最终导致Excel对话框:“microsoft excel正在等待另一个应用程序完成一个ole动作”。另一个不可思议的事情是,我们所做的一切实际上已成功发生,用户只需获得此对话框并且必须点击“确定”(并且遇到不必要的延迟)。
所有迹象都表明延迟发生在客户端。如果我完全删除了Windows窗体登录对话框,我们看不到任何延迟,并且所有操作都完成,而且没有任何提示。
一时兴起,我完全删除了代码以提示实际凭据并硬编码我们的测试帐户凭据。而且,它工作正常。如果我采用完全相同的代码并且只是实例化一个空白的Windows窗体,即new System.Windows.Forms.Form();
并且对它不执行任何操作,那么我通过我们的请求获得完全相同的行为,所有内容都会阻塞1分29秒。然后,我们的请求成功,但客户端获得上述Excel对话框。
我们也有通过功能区控件公开的完全相同的功能,工作正常,唯一的区别是:1。不涉及宏,2。我们在工作进行时显示进度对话框。
我们已经验证所有UI元素都在主Excel线程上呈现/处理,除了主线程外,我们不做任何与Excel交互的操作。不会引发异常(在调试器下运行时验证,并且在抛出所有异常时中断)。
我认为我们做错了什么,直到我只是实例化了一个空白的Windows窗体(请注意 - 它从未显示过,只是实例化)并且我可以重现这种行为。
有没有人看过这个或知道如何解决?
答案 0 :(得分:0)
这不是答案,但我认为它不适合作为评论。另外,根据目前的信息,我不确定答案是否可行。
是的,确定,代码是专有的。但是,你将不得不展示一些,否则这将无处可去。我现在能做的就是提供一些值得关注的东西。
使用加载项可能很难知道您实际使用的是什么线程。在创建登录表单之前,请将这些内容放入:
ApartmentState threadState = Thread.CurrentThread.GetApartmentState();
if (threadState != ApartmentState.STA)
{
// put a break or some warning like console.Writeline(threadState);
}
如果它不是STA线程,则无法实例化Window Message泵 - 嗯,这太强了:消息泵应该只在STA线程上,虽然我认为它们可以在MTA线程上,但它会导致问题。 / p>
如果你有一个UI元素的引用,继承自Control的东西,你可以检查它是否需要调用来改变它:
if (control.InvokeRequired)
{
// You're not on the GUI thread
}
如果其中任何一个失败,你可能不在你想到的主题上。
你能确定延迟的位置吗?您说您正在使用Windows窗体来获取凭据。你可以调试代码并逐步查看延迟发生的位置吗?也许从Show()表单之前到主代码路径之间的步骤?你能显示延迟发生的代码吗?
只是尝试一些事情。