简体   繁体   English

从Excel中的宏实例化Windows窗体会导致对话框“ Microsoft Excel正在等待另一个应用程序完成ole操作”

[英]Instantiating Windows Form from macro in Excel causes dialog “microsoft excel is waiting for another application to complete an ole action”

Apologies for not being able to post any code examples (I've not yet been able to distill down to a small, reproducible codebase and the code I have is proprietary). 抱歉,无法发布任何代码示例(我尚未能够精炼成小的可复制代码库,而我拥有的代码是专有的)。

My situation is this: I have an Excel add-in, developed using Excel DNA, that pulls data from a REST web service that requires authentication. 我的情况是这样的:我有一个使用Excel DNA开发的Excel加载项,该加载项从需要身份验证的REST Web服务中提取数据。 The add-in stores credentials on a per-session basis, but does not persist between instances of Excel. 加载项按会话存储凭据,但在Excel实例之间不保留。 There also exists a macro that is exposed to the users that allow them to invoke the code in the add-in to pull the data from the web service. 还存在一个向用户公开的宏,该宏允许用户调用外接程序中的代码以从Web服务提取数据。

The problem occurs in that if the user has not previously logged in, we pop up a Windows Form dialog asking for credentials. 发生问题是,如果用户以前未登录,我们将弹出Windows窗体对话框,要求提供凭据。 This works fine. 这很好。 After successful login, our logic commences (in one test, there's 6 concurrent requests) to pull the data from the web service. 成功登录后,我们的逻辑开始(在一个测试中,有6个并发请求)以从Web服务中提取数据。 There's a little back and forth (request the data, it's unauthorized, login, request again, pull the data, etc). 来回有点(请求数据,未经授权,登录,再次请求,提取数据等)。 If the login happens programmatically (no Windows Form is presented or instantiated), everything works fine. 如果登录是以编程方式发生的(没有显示或实例化Windows Form),则一切正常。

The problem I'm seeing is that when Windows Forms is involved, I'm seeing a 1 minute, 29 second delay (plus/minus a few fractions of a second) between the authorized request and getting the data back. 我看到的问题是,当涉及Windows窗体时,我看到授权请求和取回数据之间存在1分钟29秒的延迟(正负几分之一秒)。 This delay ends up resulting in an Excel dialog: "microsoft excel is waiting for another application to complete an ole action". 这种延迟最终导致一个Excel对话框:“ Microsoft excel正在等待另一个应用程序完成ole操作”。 The other wonky thing is that everything we have done has actually happened successfully, the user just gets this dialog and has to hit "OK" (and experience an unnecessary delay). 另一个不可思议的事情是,我们所做的一切实际上都已成功完成,用户仅获得此对话框并必须单击“确定”(并经历了不必要的延迟)。

All indications are that the delays are occurring on the client side. 所有迹象表明延迟发生在客户端。 If I completely remove the Windows Forms login dialog, we see no delays, and all actions complete with no prompts at all from excel. 如果我完全删除了Windows Forms登录对话框,则不会出现任何延迟,并且所有操作都将完全完成,而Excel根本没有任何提示。

On a whim, I completely removed the code to prompt with actual credentials and hardcoded our test account's credentials. 一时兴起,我彻底删除了代码以提示输入真实凭据,并对测试帐户的凭据进行了硬编码。 And, it works fine. 而且,它工作正常。 If I take that exact same code and just instantiate a blank Windows Form, ie new System.Windows.Forms.Form(); 如果我使用完全相同的代码,只是实例化一个空白的Windows窗体,即new System.Windows.Forms.Form(); and do nothing with it, I get the exact same behavior in that part way through our requests, everything blocks for 1 minute, 29 seconds. 却什么也没做,在我的请求中,我得到了完全相同的行为,所有内容都阻塞了1分钟29秒。 Then, our request succeeds, but the client gets the aforementioned Excel dialog. 然后,我们的请求成功,但是客户端获得了前面提到的Excel对话框。

We also have the exact same functionality exposed through a Ribbon control that works fine, the only 2 differences are: 1. no macros involved, 2. we display a progress dialog while the work is going on. 通过功能区控件,我们还具有完全相同的功能,可以正常工作,仅有的两个区别是:1.不涉及宏,2.在工作进行时显示进度对话框。

We have verified that all UI elements are rendered/processed on the main Excel thread, and we do not do anything to interact with Excel, except on the main thread. 我们已经验证了所有UI元素都是在Excel主线程上呈现/处理的,并且除了主线程外,我们不做任何其他与Excel交互的操作。 No exceptions are raised (verified while running under the debugger with break on all exceptions thrown). 不引发任何异常(在调试器下运行时进行验证,并抛出所有异常。)

I thought we were doing something wrong, until I just instantiated a blank Windows Form (mind you - it was never even shown, just instantiated) and I could reproduce the behavior. 我以为我们做错了什么,直到我实例化了一个空白的Windows窗体(提醒您-它从未显示过,只是实例化了),并且可以重现此行为。

Has anyone seen this or know how to resolve? 有没有人看过或知道如何解决?

This isn't an answer, but I don't think it'll fit as a comment. 这不是答案,但我认为它不适合作为评论。 Also with the current info I'm not sure an answer is possible. 另外,根据当前信息,我不确定答案是否可能。

Yes, sure, the code is proprietary. 是的,可以肯定,该代码是专有的。 However, you're going to have to show some of it or this isn't going to get anywhere. 但是,您将不得不展示其中的一些内容,否则将无处可做。 All I can do right now is offer some things to look at. 我现在所能做的就是提供一些要看的东西。

With add-ins it can be very difficult to know what thread you're actually on. 使用外接程序,很难知道您实际在哪个线程上。 Just before you create the login form, put these lin es: 在创建登录表单之前,请输入以下行:

    ApartmentState threadState = Thread.CurrentThread.GetApartmentState();
    if (threadState != ApartmentState.STA)
    {
        // put a break or some warning like console.Writeline(threadState);
    }

If it's not an STA thread then a Window Message pump cannot be instantiated - well, that's too strong: message pumps should only be on STA threads and although I think they can be on an MTA thread it will lead to problems. 如果它不是STA线程,则无法实例化Window Message Pump-好吧,这太强大了:消息泵应仅位于STA线程上,尽管我认为它们可以位于MTA线程上,但这会导致问题。

If you have a reference to a UI element, something that inherits from Control, you can check whether it needs Invoking to change it: 如果您有对UI元素(继承自Control的元素)的引用,则可以检查是否需要调用才能对其进行更改:

if (control.InvokeRequired)
{
    // You're not on the GUI thread
}

If either of these fail, you're probably not on the thread you think. 如果其中任何一个失败,那么您可能不在您认为的线程上。

Can you identify where the delay is? 您能确定延迟在哪里吗? You say you're using a Windows Form to get the credentials. 您说您正在使用Windows窗体来获取凭据。 Can you debug the code and step through to see where the delay happens? 您可以调试代码并逐步查看延迟发生的位置吗? Maybe step through from before Show()ing the form to when it's back on the main code path? 也许从Show()之前的表单逐步执行到何时返回主代码路径? Can you show the code where the delay occurs? 您可以显示延迟发生的代码吗?

Just some things to try. 只是一些尝试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM