Problems exiting C# program that uses R.Net - c#

I have a small program in C# that loads the R.Net library to outsource some calculations that I can't do in c#, namely the Twitter anomaly detection library. Unfortunately, when the code finishes the console window it runs in hangs. If I run it in debug, code execution seems to be error free, so I suspect it's something to do with cleanup of the REngine as I (eventually) get an error as per this image.
After which I'll get another pop up from VS stating "Debugging is stopped but is not yet complete, either force it to stop by pressing this button or continue to wait".
Code is approximately as follows:
class SHESD_Test
{
private static REngine engine;
internal SHESD_Test(IEnumerable<Double> d)
{
try
{
if(engine==null)
{
engine = REngine.GetInstance();
engine.Initialize();
engine.Evaluate("library(AnomalyDetection)"); //Loads Twitter library
}
var dInR = engine.CreateNumericVector(d.toArray());
engine.SetSymbol("data", dInR);
var outVar = engine.Evaluate("outVar <- AnomalyDetectionVec(data, max_anoms=0.02, direction='both', plot=FALSE, period=96)");
/* Some other stuff that grabs data out of outVar in R and stores in member variables */
}
catch (Exception e)
{ /* Log error */ }
}
//Called from elsewhere once everything is complete, but behaviour is the same if I don't call it
internal static void cleanup()
{
engine.ForceGarbageCollection();
engine.Dispose();
engine == null;
}
}
Googling the error code, it looks like a timeout has expired, but for the life of me I can't figure out why.
The code itself executes fine, it's only in the exit from main(), and not the bit where the REngine falls out of scope, so perhaps in garbage collection things are going awry?

Digging further, the root cause is in the library function generating a plot window in it's return value, even when told not to. Their code is:
# Lastly, return anoms and optionally the plot if requested by the user
if(plot){
return (list(anoms = anoms, plot = xgraph))
} else {
return (list(anoms = anoms, ***plot = plot.new()***)) # <-Looky here!
}
Adding to my code the following line when I'm done with the engine:
engine.Evaluate("graphics.off()");
closes the strange empty window, which doesn't seem to be able to be closed by either the ForceGarbageCollection or Dispose methods - probably leaving things hanging about waiting for something that will never happen, and thus triggering this timeout exception window.

Related

WPF cannot close Application instance for running it a second time

I have an Console Application started as [STAThread].
That application should open a seperate Wpf UI for entering some settings.
The functions for that:
private static void openUI()
{
var application = new System.Windows.Application();
//referenced project in the same solution
var ui = new ManagerUI.MainWindow();
//blocks execution
application.Run(ui);
application.Shutdown();
}
Opening the UI for the first time works as expected.
The problem occurs when opening the UI for the second time.
I get an System.InvalidOperationException, saying that I cannot run more than one Application-Instance in the same AppDomain.
For saving ram, it must be closed between the operations.
I also tried to create the System.Windows.Application in the constructor.
But as soon as I run the application the second time, I get a very similiar exception.
The InitializeComponents() method of the UI throws an System.InvalidOperationException, saying that the Object is going to be terminated.
The StackTraces shows that the error appears when the xaml is parsed, so I conclude it cannot open it, because it is still opened by the first execution.
Neither calling ui.Close() nor calling application.Shutdown() solves the problem (Environment.Exit() closes everything, including my Console Application).
The ram profiler indicates, not everything was closed correctly because it shows an higher use after the Window was closed, than before it was opened in the firts place.
How do I properly close the Application instance, or how do I re-use it to run an Wpf Application multiple times?
Having looked at the source code for the Application class, it doesn't look like you will be able to work around this, as various static fields are initialized by the class constructor:
public Application()
{
...
lock(_globalLock)
{
if (_appCreatedInThisAppDomain == false)
{
...
_appInstance = this;
...
_appCreatedInThisAppDomain = true;
}
else
{
throw new InvalidOperationException(...);
}
}
}
...
static private object _globalLock;
static private bool _appCreatedInThisAppDomain;
static private Application _appInstance;
...
Basically the constructor sets _appCreatedInThisAppDomain to true, and as that field is private you have no way of setting it back*.
I think the only way of achieving something similar to what you want is to write a separate WPF application, then use the Process class to launch that from your console application. Alternatively, you could theoretically create a separate AppDomain to host your WPF stuff but that would be a lot more complicated.
[*] other than using Reflection, but let's not go there!
You may create a class that derives from MarshalByRefObject:
public class AppDomainWrapper : MarshalByRefObject
{
public void openUI()
{
var application = new System.Windows.Application();
var ui = new Window();
application.Run(ui);
application.Shutdown();
}
}
...and execute its openUI() method in its own application domain:
[STAThread]
static void Main(string[] args)
{
const int n = 2;
for (int i = 0; i < n; ++i)
{
AppDomain appDomain = AppDomain.CreateDomain("AppDomain");
AppDomainWrapper application = appDomain.CreateInstanceAndUnwrap(typeof(AppDomainWrapper).Assembly.FullName, typeof(AppDomainWrapper).FullName) as AppDomainWrapper;
application.openUI();
AppDomain.Unload(appDomain);
}
}
Have a look at this question:Does a WPF Application Actually Need Application.Run?.
Basically it says, that you can open windows using window.ShowDialog() method without Application instance
The think is that Application.Run does not do anything important but run Dispatcher loop. ShowDialog have its own Dispatcher. You can create Application singleton instance however, since it contains some shared resources.
Hack(run it after application.Shutdown()). I use this in tests:
var field = typeof(Application).GetField(
"_appCreatedInThisAppDomain",
BindingFlags.Static | BindingFlags.NonPublic) ??
throw new InvalidOperationException(
"Field is not found: _appCreatedInThisAppDomain.");
field.SetValue(null, false);
Steven Rands shows the problem.
I have the same problem in an external add-in. But I need an application object for xaml resources and a valid Application.Current.
In my eyes this is a bug. If you call Shutdown() this member should also be reset to false.

Catch does not perform its code

I'm developing C# application for windows phone 8.1 (Silverlight). Lately I've came across the problem connected to application falling asleep and storyboards.
The construction goes as follows:
class X : DependencyObject
{
public static readonly DependencyProperty vProperty =
DependencyProperty.Register("v", typeof(double), typeof(X), new PropertyMetadata(0.0));
public double v
{
get
{
return (double)GetValue(vProperty);
}
set
{
SetValue(vProperty, value);
}
}
private Storyboard _storyboard;
void Prepare()
{
_storyboard = new Storyboard();
var animation= new DoubleAnimation
{
From = 0,
To = 1,
BeginTime = 0,
Duration = 0,
};
_storyboard.Children.Add(animation);
Storyboard.SetTarget(animation, this);
Storyboard.SetTargetProperty(animation, vProperty);
}
void Go()
{
_storyboard.Begin();
}
}
There is a NullReferenceException thrown from inside of _storyboard.Begin() if application is placed in background between "Prepare" and "Go" (about 10% reproduction rate). Of course it ends up with crash.
I was not able to determine problem source and as I need quickfix for that I've decided to just catch this NullRefereneceException in this rare scenario. This is where real question starts. I've changed "Go" implementation to:
public void Go()
{
Debug.WriteLine("BreakPoint 1");
try
{
_storyboard.Begin();
}
catch (NullReferenceException)
{
Debug.WriteLine("BreakPoint 2");
}
}
Afterwards the crash is not reproducible at all, but the problem is that "BreakPoint 2" is never hit (no printout in Output either). "BreakPoint 1" is normally hit and printed as well. Changing NullReferenceException to other Exception type (not parent type ofc) causes crash to reappear.
So... What's going on here? Is this crash cached or not? What kind of weird behavior is that? Is it safe to assume that it will work as expected?
Additional question: Maybe you know why the original code crashes in the first place?
EDIT:
End of stack trace of internalException of TargetInvocationExceptions looks as follows:
at MS.Internal.XcpImports.CheckHResult(UInt32 hr)
at MS.Internal.XcpImports.Storyboard_Begin(Storyboard storyboard)
at System.Windows.Media.Animation.Storyboard.Begin()
at X.Go()
I know that you've said that you've tried to use parent types for NullReferenceException, but please try the following without running in the debugger:
public void Go()
{
Debug.WriteLine("BreakPoint 1");
try
{
_storyboard.Begin();
}
catch (Exception)
{
Debug.WriteLine("BreakPoint 2");
System.Diagnostics.Debugger.Break();
}
}
My suspicion is that the catch is not firing because you are running from within the debugger. Also try System.Diagnostics.Debugger.Launch(); in the catch if .Break(); does not work. And finally also try throw; in the catch if .Launch(); does not work.
If the debugger attempts to launch in either case, then you have another clue.
UPDATE:
I can't give you all of the reasons why this might happen as it may not be possible to determine precisely what is causing it in your situation.
I've seen behavior like this due to use of multithreading. Multithreading can behave differently when running with a debugger attached then without. Timing issues and race conditions can prevent exceptions from being thrown while in the debugger that otherwise may occur frequently when there is no debugger attached.
I've also encountered instances where System.Diagnostics.Debugger.IsAttached was used in third party code and even my team's code which caused the application to behave differently based on if statements using this check.
And lastly, I've had times where I could not come up with a specific reason why the behavior was occurring. I've learned to use the System.Diagnostics.Debugger.Break() method whenever I see behavior exhibited differently depending on whether a debugger is attached or not. Sometimes it really is just a gut feeling.

How do I generate keystrokes in a non-form application

So I have a huge program and decided I should make one of the methods run in a separate thread. So I put the method in a separate class, an activated it on my form. It seemed to worked just how I wanted it to until it got to part where it gave me this error:
SendKeys cannot run inside this application because the application
is not handling Windows messages. Either change the application to
handle messages, or use the SendKeys.SendWait method.
I tried looking for the answer online. I think I saw something about how SendKeys only works in a Form or something.
Can anyone tell me a way to simulate a keystroke without using SendKeys, OR a way to get SendKeys to work in a different, non-form thread?
Your console application needs a message loop. This is done through the Application class. You will need to call Application.Run(ApplicationContext).
class MyApplicationContext : ApplicationContext
{
[STAThread]
static void Main(string[] args)
{
// Create the MyApplicationContext, that derives from ApplicationContext,
// that manages when the application should exit.
MyApplicationContext context = new MyApplicationContext();
// Run the application with the specific context. It will exit when
// the task completes and calls Exit().
Application.Run(context);
}
Task backgroundTask;
// This is the constructor of the ApplicationContext, we do not want to
// block here.
private MyApplicationContext()
{
backgroundTask = Task.Factory.StartNew(BackgroundTask);
backgroundTask.ContinueWith(TaskComplete);
}
// This will allow the Application.Run(context) in the main function to
// unblock.
private void TaskComplete(Task src)
{
this.ExitThread();
}
//Perform your actual work here.
private void BackgroundTask()
{
//Stuff
SendKeys.Send("{RIGHT}");
//More stuff here
}
}
I Know this not an answer, but this how i used to do using ActiveX and Script
Set ws = CreateObject("WScript.Shell")
str = "Hi there... ~ Dont click your mouse while i am typing." & _
" ~~This is a send key example, using which you can send your keystrokes"
ws.Run("notepad.exe")
WScript.Sleep(1000)
For c=1 To Len(str)
WScript.Sleep(100) 'Increase the value for longer delay
ws.SendKeys Mid(str,c,1)
Next
Save this code as file.vbs and double click to execute in windows machine.

C# Execution stops without error when trying to call a method

First of all I am stumped. I have a search-module for a CMS that runs fine on one site, but it won't run as it's supposed to on another site.
I have this code I call both with an Ajax call and simply when loading the search site:
private string GetSearchContent()
{
Query q = GetQuery();
//for each area, set it up, perform search and render result
IArea products = new ProductArea(GetEcomExcludedGroupIDs(), GetEcomLanguage()).Search(q);
IArea pages = new PageArea(GetAreaId())
.Search(q);
IArea news = new NewsArea(GetIncludedNewsCategoryIDs())
.Search(q);
....
}
The important part here is the Search function. This is implemented in the classes, but for some reason the code won't be executed.
I have tried splitting the code up so I am sure that is where the error lies. The freaky part is that it does not throw any exceptions, but it just stops executing whenever I try to call the Search function. It doesn't even enter the function.
The Search function looks like this:
public override IArea Search(Query q)
{
log.Debug("Product search");
....
}
The function it overrides is simply an abstract function on an interface that declares the function.
I have tried copying the function to the same class that are executing it with no luck, and I have tried accessing other functions on the classes, and that worked fine.
My question is then. What could cause this behavior? I have tried looking around but couldn't really find any others with the same problem. And as mentioned before, the exact same code is running smoothly on another site.
I really hope someone can help me get closer to a fix, or at least to understand the problem.
The question is unanswerable as written. You assert that the Search method never runs, and that the faulty line is this one:
IArea news = new NewsArea(GetIncludedNewsCategoryIDs()).Search(q);
There are a few different things that could be wrong outside of the Search method:
The NewsArea constructor throws an exception
The GetIncludedNewsCategoryIDs method throws an exception
Either of the above could call into unmanaged code and generate a native Win32 exception, which under some circumstances will simple cause the process to terminate rather than ever returning to managed code.
You state that "there is no try-catch" -- all the more reason to disbelieve your assertion that the method just stops without throwing an exception. Try the following for diagnostic purposes:
try
{
IArea news = new NewsArea(GetIncludedNewsCategoryIDs()).Search(q);
}
catch (Exception e)
{
Logger.Log("Caught in the act: " + e.ToString());
throw;
}
If you've run this and still see that the execution stops without logging any exception, then we'll look at other possibilities.

AccessViolationException in debugger with only managed code and WCF service

This application has a WCF web service that is called by a WinForms app. The WinForms app has a class WCFCache to manage data from the service. There is a section like this in that class to manage an optional custom configuration section that a subset of the machines have:
private bool? m_HasCustomConfiguration = null;
public bool HasCustomConfiguration
{
get
{
if (m_HasCustomConfiguration == null)
m_HasCustomConfiguration = (CustomConfiguration != null);
return (bool)m_HasCustomConfiguration;
}
}
private WCFService.CustomConfiguration m_CustomConfiguration = null;
public WCFService.CustomConfiguration CustomConfiguration
{
get
{
if (m_CustomConfiguration == null)
{
if (m_HasCustomConfiguration.HasValue
&& !m_HasCustomConfiguration.Value)
return null;
try
{
using (WCFService.WCFServiceClient wcf = new WCFService.WCFServiceClient())
{
m_CustomConfiguration =
wcf.GetCustomConfiguration(Machine.ProcessID);
// Above method returns null if no record exists.
m_HasCustomConfiguration = (m_CustomConfiguration != null);
}
} catch (Exception e) {
// Error logging & re-throw
}
}
return m_CustomConfiguration;
}
}
When I step through the debugger in code that calls either of the above properties like this:
if (!Program.WCFCache.HasCustomConfiguration)
return new List<CustomComponents>();
...it throws the following exception:
System.AccessViolationException was unhandled
Message="Attempted to read or write protected memory. This is often an indication that other memory is corrupt."
Source="System.Windows.Forms"
...
When I step onto the line containing the reference, there is a long pause, followed by a VS popup with the exception.
The exception doesn't appear when I just put a breakpoint after the above code has executed. It doesn't even appear when I put a breakpoint inside the accessors of the properties. It only occurs when I step onto a line with one of those properties from the outside. (So there is a workaround, but it can be a pain.)
Why is this happening? Can I stop it?
Edit: The whole application was written in the last year in 3.5 C#/.NET with WCF communicating between components; meaning, we don't have legacy unmanaged DLLs. Just two unmanaged calls: one to advapi32.dll when the WinForms app is loading, in the username detection procedure. The issue I'm having happens only in this one place in the code, in a place that is about as unrelated to the login section as you can get. The other is to kernel32.dll, in a GC force-flush long after anything is done with the results from calls like the one above.
Are you using any P/Invoke or other such native code? Odds are, that's where you should start looking.
This exception is a symptom of a larger problem, namely memory corruption (that what the exception says, after all). If this was a native application, you'd get a crash.
So, look at any native calls, make sure they're operating correctly, maybe run them under a debugger to try and trap the error closer to home.
Sorry, can't really give better advice given the circumstances.
I eventually found that others have encountered this situation and that it is likely a Visual Studio bug. I was using VS 2008 when the problem occurred.

Categories

Resources