use C# Excel DNA with C# Window Form - excel

ContextSwitchDeadlock occurred Message: Managed Debugging Assistant 'ContextSwitchDeadlock' has detected a problem in 'C:\Program Files\Microsoft Office\Office15\EXCEL.EXE'. Additional information: The CLR has been unable to transition from COM context 0xfd30d6e0 to COM context 0xfd30d5b8 for 60 seconds. The thread that owns the destination context/apartment is most likely either doing a non pumping wait or processing a very long running operation without pumping Windows messages. This situation generally has a negative performance impact and may even lead to the application becoming non responsive or memory usage accumulating continually over time. To avoid this problem, all single threaded apartment (STA) threads should use pumping wait primitives (such as CoWaitForMultipleHandles) and routinely pump messages during long running operations.
Working on Excel DNA have a function to refresh sheet also refresh and update sheet but I'm getting exception as I'm share

First open Exception dialog using ctrl+alt+E command then go Managed Debugging Assistants and uncheck ContextSwitchDeadlockenter image description here

Related

Blueprsim is not detecting any thing on page when object is ran from Process studio

I'm facing an annoying issue in Blueprism a little help will be appreciated.
The error is when I run the task I have created in object studio directly in object studio it runs successfully but when I try to run the same task from process studio using action It throws an error. The application is launched but get this error. (Application is web-based.)
Internal: Failed to perform step 1 in Read Stage 'Reader1' on page 'Main' - No elements match the supplied query terms
this is Application Modeller Settings
Application Modeller
And this is how I call it in Process
Object Called in process
Action Properties
Wait Settings are following
When I try to highlight the link it does highlight it.
I think that after your Reader1 should be a decision if element was found or not and then you can proceed with log-in. But I'd check if the element you're spying is working correctly. Maybe try passing value of reader from object to process.
A process in BluePrism can have different speed of execution depending on the way you're running it.
If you're running application using "Step" function (hotkey F5), then BluePrism waits a long time between executing actions. A "Step above" (hotkey F10) is much faster, but the fastest possible speed of execution is from control room.
The delay from "Step", or "Step above" can be enough to make process work during the development. Once the process is moved to control room, then the delay is gone and sometimes the process might be running too fast. It can happen, that the BluePrism is trying to interact with the element that does not yet exist.
To make process work in control room, you need to have additional wait stages that will ensure that the process is not running ahead of the applications that are being automated. Whenever you're interacting with any element then you need to be sure that it exists.
i suspect that you're waiting for an element, but then you're trying to read a different one. It's important to wait for the exact element that you want to interact with, as elements can appear in an order, that can make your process crash.

OpenFileDialoug Current Thread Must Be STA before OLE calls made

Can someone explain to me what this error I'm seeing is?
Current thread must be set to single thread apartment (STA) mode before OLE calls can be made.
Specifically, I'm trying to open the SaveFileDialog/OpenFileDialog within C++/CLI on a form.
SaveFileDialog^ saveFileDialog1 = gcnew SaveFileDialog;
saveFileDialog1->ShowDialog();
if (saveFileDialog1->ShowDialog() == System::Windows::Forms::DialogResult::OK)
{
s = saveFileDialog1->OpenFile();
}
s->Close();
}
The error that is throwing is
An unhandled exception of type 'System.Threading.ThreadStateException' occurred in System.Windows.Forms.dll
Additional information: Current thread must be set to single thread apartment (STA) mode before OLE calls can be made. Ensure that your Main function has STAThreadAttribute marked on it. This exception is only raised if a debugger is attached to the process.
I'm not really familiar with what this error is saying. I know just a bit about threading, but I'm not sure how threading would be an issue here. I've seen some people reference things like STAThread without providing a clear explanation as to what it does, and Microsoft's documentation makes no mention of having this exception thrown when calling SaveFileDialog/OpenFileDialog, or how to handle it.
Thanks!
When you use OpenFileDialog then a lot of code gets loaded into your process. Not just the operating system component that implements the dialog but also shell extensions. Plugins that programmers write to add functionality to Windows Explorer. They work in that dialog as well. There are many, one you are surely familiar with is the extension that makes a .zip file look like a folder.
One thing Microsoft did when they designed the plug-in interface is to not force an extension to be thread-safe. Because that is very hard to do and often a major source of bugs. They made the promise that the thread that creates the plugin instance is also the thread on which any call to the plugin is made. Thus ensuring that the plugin is always used in a thread-safe manner.
That however requires a little help from you. You have to make a promise that your thread, the one that calls OpenFileDialog::Show(), observes the requirements of a single-threaded apartment. STA for short. You make the promise with the [STAThread] attribute on your program's Main() entrypoint. Or if it is a thread that you created yourself then by calling Thread::SetApartmentState() before you start it.
That's just a promise however, you also have to implement what you promised. Takes two things, you promise to never block the thread and you promise to pump a message loop. Application::Run() in a .NET program. The never-block promise ensures that you won't cause deadlock. And the message loop promise says that you implement a solution to the producer-consumer problem.
This should never be a problem, it is very unclear how this got fumbled in your project. Another implicit requirement for a dialog is that it must have an owner. Another window on which it can be on top of. If it doesn't have one then there are very high odds that the user never sees the dialog. Covered by another program's window, the user can only ever find it back by accident. When you create windows then you always also must call Application::Run() so the windows can respond to user input. Use the boilerplate code in a C++/CLI app so this is done correctly.

Does the inability of IMessageFilter to handle 0x800AC472 (VBA_E_IGNORE) make implementing IMessageFilter irrelevant?

From msdn it seems that IMessageFilter doesn't handle all exceptions, for example, at some points, office applications 'suspend' their object model, at which point it cannot be invoked and throws: 0x800AC472 (VBA_E_IGNORE)
In order to get around this, you have to put your call in a loop and wait for it to succeed:
while(true)
{
try
{
office_app.DoSomething();
break;
}
catch(COMException ce)
{
LOG(ce.Message);
}
}
My question is: if this boiler-plate code is necessary for each call to the office app's object model, is there any point in implementing IMessageFilter?
Yes, the two mechanisms are independent. IMessageFilter is a general COM mechanism to deal with COM servers that have gone catatonic and won't handle a call for 60 seconds. The VBE_E_IGNORE error is highly specific to Excel and happens when it gets in a state where the property browser is temporarily disabled. Think of it as a modal state, intentionally turned on when Excel needs to perform a critical operation that must complete before it can handle out-of-process calls again. A lock if you will. It is not associated with time, like IMessageFilter, but purely by execution state. Geoff Darst of the VSTO team gives some background info in this MSDN forums thread.
Having to write these kind of retry loops is horrible of course. Given that it is an execution state issue and assuming that you are doing interop with Excel without the user also operating the program, there ought to be a way to sail around the problem. If you are pummeling Excel from a worker thread in your program then do consider reviewing the interaction between threads in your code to make sure you don't create a case where the threads are issuing Excel calls at roughly the same time.

Why the window of my vb6 application stalls when calling a function written in C?

I'm using 3.9.7 cURL library to download files from the internet, so I created a dynamic bibioteca of viculo. dll written in C using VC + + 6.0 the problem is that when either I call my function from within my vb6 application window locks and unlocks only after you have downloaded the file how do I solve this problem?
The problem is that when you call the function from your DLL, it "blocks" your app's execution until it gets finished. Basically, execution goes from the piece of code that makes the function call, to the code inside of the function call, and then only comes back to the next line after the function call after the code inside of the function has finished running. In fact, that's how all function calls work. You can see this for yourself by single-stepping through your code in the VB 6 development environment.
You don't normally notice this because the code inside of a function being called doesn't take very long to execute before control is returned to the caller. But in this case, since the function you're calling from the DLL is doing a lot of processing, it takes a while to execute, so it "blocks" the execution of your application's code for quite a while.
This is a good general explanation for the reason why your application window appears to be frozen. A bit more technically, it's because the message pump that is responsible for processing user interaction with on-screen elements is not running (it's part of your code that has been temporarily suspended until the function that you called finishes processing). This is a bit more difficult for a VB programmer to appreciate, since none of this nitty-gritty stuff is exposed in the world of VB. It's all happening behind the scenes, just like it is in a C program, but you don't normally have to deal with any of it. Occasionally, though, the abstraction leaks, and the nitty-gritty rears its ugly head. This is one of those cases.
The correct solution to this general problem, as others have hinted at, is to run lengthy operations on a background thread. This leaves your main thread (right now, the only one you have, the one your application is running on) free to continue processing user input, while the other thread can process the data and return that processed data to the main thread when it is finished. Of course, computers can't actually do more than one thing at a time, but the magic of the operating system rapidly switching between one task and another means that you can simulate this. The mechanism for doing so involves threads.
The catch comes in the fact that the VB 6 environment does not have any type of support for creating multiple threads. You only get one thread, and that's the main thread that your application runs on. If you freeze execution of that one, even temporarily, your application freezes—as you've already found out.
However, if you're already writing a C++ DLL, there's no reason you can't create multiple threads in a VB 6 app. You just have to handle everything yourself as if you were using another lower-level language like C++. Run the C++ code on a background thread, and only return its results to the main thread when it is completely finished. In the mean time, your main thread is free.
This is still quite a bit of work, though, especially if you're inexperienced when it comes to Win32 programming and the issues surrounding multiple threads. It might be easier to find a different library that supports asynchronous function calls out-of-the-box. Antagony suggests using VB's AsyncRead method. That is probably a good option; as Karl Peterson says in the linked article, it keeps everything in pure VB 6 code, which can be a real time saver as well as a boon to future maintenance programmers. The only problem is that you'll still have to process the data somehow once you obtain it. And if that's slow, you're right back where you started from…
Check out this article, which demonstrates how to asynchronously transfer large files using a little-known method in user controls.

Unusual exception - reading/updating Excel spread sheet

I am reading content of a full spread sheet to a datatable
Then iterate through Table.Rows Query Remote database (Oracle), and Create/Update/Delete ADS account
Then update the Excel row with the result (status)
Most of the time things go smoothly, but intermittently I get this exception:
ContextSwitchDeadlock was detected
Message: The CLR has been unable to transition from COM context 0x2119a8 to COM context 0x211b18 for 60 seconds. The thread that owns the destination context/apartment is most likely either doing a non pumping wait or processing a very long running operation without pumping Windows messages.
This situation generally has a negative performance impact and may even lead to the application becoming non responsive or memory usage accumulating continually over time. To avoid this problem, all single threaded apartment (STA) threads should use pumping wait primitives (such as CoWaitForMultipleHandles) and routinely pump messages during long running operations.
What could be causing this ?

Resources