Starting Xamarin foreground service sample crashes - c#

I'm looking to create a Xamarin foreground service and thought taking the sample from https://github.com/xamarin/monodroid-samples/tree/main/ApplicationFundamentals/ServiceSamples/ForegroundServiceDemo would be a good first step.
After building and deploying to my Samsung S10 it just crashes when clicking 'Start Service'.
The line it fails on is TimeStampService.cs line 155, on the code:
var pendingIntent = PendingIntent.GetActivity(this, 0, notificationIntent, PendingIntentFlags.UpdateCurrent);
With null reference exception. The stack trace:
at Android.Runtime.JNINativeWrapper._unhandled_exception (System.Exception e) [0x0000e] in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Android.Runtime/JNINativeWrapper.g.cs:12
at Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PPLII_I (_JniMarshal_PPLII_I callback, System.IntPtr jnienv, System.IntPtr klazz, System.IntPtr p0, System.Int32 p1, System.Int32 p2) [0x00022] in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Android.Runtime/JNINativeWrapper.g.cs:221 at (wrapper native-to-managed) Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PPLII_I(intptr,intptr,intptr,int,int)
I've tried a few things, including updating to latest versions of references, but still nothing I do fixes this.
I tried creating a new background service from scratch and still get the same error.
Does anyone have any ideas how I can fix this?

Did you add the foreground service permission in the AndroidManifest.xml?
Such as:
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
Update
You can try to use the code in my old answer:Trouble getting local notifications to fire in Android when the application is closed (using AlarmManager)
In addition, start it in the mainactivity:
Intent intent = new Intent(this, typeof(ForgroundServiceDemo));
StartForegroundService(intent);

Related

An error on GetMainWindow function FlaUI C#

I'm using FlaUI library to automate desktop app.
I took an error on try to run code to take a window of launched program. Error: Could not find process with id: ***'
Details of error.
System.Exception
HResult=0x80131500
Message=Could not find process with id: 13536
Source=FlaUI.Core
StackTrace:
at FlaUI.Core.Application.FindProcess(Int32 processId)
at FlaUI.Core.Application.<WaitWhileMainHandleIsMissing>b__33_0()
at FlaUI.Core.Tools.Retry.<>c__DisplayClass12_0.<WhileTrue>b__0()
at FlaUI.Core.Tools.Retry.While[T](Func`1 retryMethod, Func`2 checkMethod, Nullable`1 timeout, Nullable`1 interval, Boolean throwOnTimeout, Boolean ignoreException, String timeoutMessage, Boolean lastValueOnTimeout, T defaultOnTimeout)
at FlaUI.Core.Application.WaitWhileMainHandleIsMissing(Nullable`1 waitTimeout)
at FlaUI.Core.Application.GetMainWindow(AutomationBase automation, Nullable`1 waitTimeout)
at Program.<Main>$(String[] args) in C:\Users\jekug\source\repos\FlaUI test\FlaUI test\Program.cs:line 10
This exception was originally thrown at this call stack:
[External Code]
ArgumentException: Process with an Id of 13536 is not running.
What can be wrong and are there other ways to take
a window in FlaUI?
Thank you
calc.exe on any newer windows is actually just a proxy executable to in the end run the "WindowsStoreApp" calculator which behaves quite differently. For those apps, you need to use LaunchStoreApp instead of Launch in order to get the correct process.

ML.net cli -- Resume a cli training after a crash

is there a way to resume an ML.net cli training to where it was before a crash?
I have a lot of data in the folder C:\Users\wwww\AppData\Local\Temp\AutoML-NNI\Experiment-9K67B4 but I do not know how to make mlnet start from there.
Detail:
I used the cli, ie "mlnet classicfiaction...."
I trained for a few days, but I made a mistake which used a lot of memory on my computer, which stopped the mlnet process. I would like to start mlnet to where it left so it can continue from there
Note: I would love to be able to stop earlier and continue/resume a training from the cli.
Thanks
w
2022-08-10 15:03:24.3091 DEBUG System.InvalidOperationException: Event we were waiting on was subject to an exception
---> System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
at System.Array.Resize[T](T[]& array, Int32 newSize)
at Microsoft.ML.Internal.Utilities.ArrayUtils.EnsureSize[T](T[]& array, Int32 min, Int32 max, Boolean keepOld, Boolean& resized)
at Microsoft.ML.Data.CacheDataView.ColumnCache.ImplOne`1.CacheCurrent()
at Microsoft.ML.Data.CacheDataView.Filler(DataViewRowCursor cursor, ColumnCache[] caches, OrderedWaiter waiter)
Relate to
https://github.com/dotnet/machinelearning/issues/6286
https://github.com/dotnet/machinelearning/issues/6287

Xamarin: OpenGL Video Encoding Locks Up on 46000 Outstanding GREFs. Performing a full GC

I have a long running video task in a Xamarin.Android app; it decodes a video file using a MediaPlayer into a custom OpenGL ES Surface then queues another Surface, encodes the data using a MediaCodec and drains into a ByteBuffer, which then is passed into a MediaMuxer based upon encoder output ByteBuffer availability. The operation works well and fast, until the video file written byte total is over ~1.3GB, at which point the video (but not audio) will lockup.
The app seems to have too many GREFs, as I'm watching them go up and down in realtime, until they're finally well above 46000 GREFs. It seems like the operating system (or app?) is having trouble dumping all of the GREFs via GC, which causes the app to get stuck in the middle of video processing. I'm monitoring the android resources and the total available memory never changes very much at the OS level; the cpu also seems to always have plenty of idle headroom (~28%).
I am outputting to the system console and watching the gref output logging using:
adb shell setprop debug.mono.log gref
The garbage collection seems to not be able to keep up after about 14 minutes. The GREF count goes up, then down, up, then down; eventually, it goes so high that the GREF count stays above 46k, with the following message looping:
09-26 15:07:11.613 I/monodroid-gc(11213): 46111 outstanding GREFs. Performing a full GC!
09-26 15:07:11.898 I/zygote64(11213): Explicit concurrent copying GC freed 9(32KB) AllocSpace objects, 0(0B) LOS objects, 70% free, 2MB/8MB, paused 434us total 63.282ms
09-26 15:07:13.470 D/Mono (11213): GC_TAR_BRIDGE bridges 22974 objects 23013 opaque 1 colors 22974 colors-bridged 22974 colors-visible 22974 xref 1 cache-hit 0 cache-semihit 0 cache-miss 0 setup 3.40ms tarjan 25.53ms scc-setup 14.85ms gather-xref 1.76ms xref-setup 0.50ms cleanup 13.81ms
09-26 15:07:13.470 D/Mono (11213): GC_BRIDGE: Complete, was running for 1798.94ms
09-26 15:07:13.470 D/Mono (11213): GC_MAJOR: (user request) time 54.95ms, stw 57.82ms los size: 5120K in use: 1354K
09-26 15:07:13.470 D/Mono (11213): GC_MAJOR_SWEEP: major size: 7648K in use: 6120K
and the GREF logs look like this... except multiplied by tens of thousands. And I can watch this number go up, then down, up then down, up then down, until the numbers are massive and eventually so far above 46k that it seems like the app (or OS?) gives up trying to clear these GREFs
grefc 38182 gwrefc 5 38182 is the number that goes massively up then down until well over 46k
09-30 22:42:11.013 I/monodroid-gref(20765): -g- grefc 38182 gwrefc 51 handle 0x98156/G from thread 'finalizer'(25420)
09-30 22:42:11.013 I/monodroid-gref(20765): +w+ grefc 38181 gwrefc 52 obj-handle 0x980f6/G -> new-handle 0xbc3/W from thread 'finalizer'(25420)
09-30 22:42:11.013 I/monodroid-gref(20765): -g- grefc 38181 gwrefc 52 handle 0x980f6/G from thread 'finalizer'(25420)
and there's also these warnings from the GC system warning: not replacing previous registered handle 0x30192 with handle 0x62426 for key_handle 0x9b1ac32
10-03 13:15:25.453 I/monodroid-gref(22127): +g+ grefc 24438 gwrefc 0 obj-handle 0x9/I -> new-handle 0x62416/G from thread 'Thread Pool Worker'(44)
10-03 13:15:25.476 I/monodroid-gref(22127): +g+ grefc 24439 gwrefc 0 obj-handle 0x30192/I -> new-handle 0x62426/G from thread 'Thread Pool Worker'(44)
10-03 13:15:25.477 I/monodroid-gref(22127): warning: not replacing previous registered handle 0x30192 with handle 0x62426 for key_handle 0x9b1ac32
10-03 13:15:25.483 I/monodroid-gref(22127): +g+ grefc 24440 gwrefc 0 obj-handle 0x9/I -> new-handle 0x62436/G from thread 'Thread Pool Worker'(44)
Additionally, it seems like the video freezes while the garbage collection is running, even when that happens without getting stuck in a loop. This is another problem I'm looking for tips or answers on.
This code was ported from another project; I noticed that the previous developer mentioned
// Even if we don't access the SurfaceTexture after the constructor returns, we
// still need to keep a reference to it. The Surface doesn't retain a reference
// at the Java level, so if we don't either then the object can get GCed, which
// causes the native finalizer to run.
I'm thinking this is the key to the problem that I'm experiencing, but what I'm confused about is how the app is supposed to continue encoding if the garbage collection can't run. I see a ton of these in the GREF logs:
10-03 13:07:04.897 I/monodroid-gref(22127): +g+ grefc 6472 gwrefc 4825 obj-handle 0x3727/W -> new-handle 0x2982a/G from thread 'finalizer'(24109)
So is this GREF log entry an indication that I need the finalizer to finish? Or is it an indication that I should have never allowed the finalizer to run before the video is finished encoding?
I did some reading about this and checked out java code doing the same type of operation. At that point I tried adding in a WeakReference to the parent class. The video encoding seems to get a lot further along with the weak reference, but it still eventually locks up.
private void setup() {
_textureRender = new TextureRender();
_textureRender.SurfaceCreated();
// Even if we don't access the SurfaceTexture after the constructor returns, we
// still need to keep a reference to it. The Surface doesn't retain a reference
// at the Java level, so if we don't either then the object can get GCed, which
// causes the native finalizer to run.
_surfaceTexture = new SurfaceTexture(_textureRender.TextureId);
Parent.WeakSurfaceTexture.FrameAvailable += FrameAvailable; // notice the Weak references here
_surface = new Surface(Parent.WeakSurfaceTexture);
}
Here's how I'm getting the weak parent reference:
public System.WeakReference weakParent;
private OutputSurface Parent {
get {
if (weakParent == null || !weakParent.IsAlive)
return null;
return weakParent.Target as OutputSurface;
}
}
public SurfaceTexture WeakSurfaceTexture {
get { return Parent.SurfaceTexture; }
}
When the app is actually locked in a GC loop, it's stuck on this
var curDisplay = EGLContext.EGL.JavaCast<IEGL10>().EglGetCurrentDisplay();
in this context:
const int TIMEOUT_MS = 20000;
public bool AwaitNewImage(bool returnOnFailure = false) {
System.Threading.Monitor.Enter (_frameSyncObject);
while (!IsFrameAvailable) {
try {
// Wait for onFrameAvailable() to signal us. Use a timeout to avoid
// stalling the test if it doesn't arrive.
System.Threading.Monitor.Wait (_frameSyncObject, TIMEOUT_MS);
if (!IsFrameAvailable) {
if (returnOnFailure) {
return false;
}
// TODO: if "spurious wakeup", continue while loop
//throw new RuntimeException ("frame wait timed out");
}
} catch (InterruptedException ie) {
if (returnOnFailure) {
return false;
}
// shouldn't happen
//throw new RuntimeException (ie);
} catch (Exception ex) { throw ex; }
}
IsFrameAvailable = false;
System.Threading.Monitor.Exit (_frameSyncObject);
//the app is locking up on the next line:
var curDisplay = EGLContext.EGL.JavaCast<IEGL10>().EglGetCurrentDisplay();
_textureRender.CheckGlError ("before updateTexImage");
Parent.WeakSurfaceTexture.UpdateTexImage ();
return true;
}
So is this an issue where I need to prevent the finalizer from running? Or is it an issue where the finalizer is causing too many GREFs? Do I need to dispose of some of these frame render SurfaceTextures before I continue processing the video? Do I need to pause the MediaPlayer and dump all of these references before I continue the read/write process?
Do I need to just optimize my code somehow? I read that if there's too many Java.Lang.Object instantiations or usages that it can cause a GREF overflow (or something like that?). I combed through my code and couldn't find anything inheriting from Java.Lang.Object that is getting run in this loop.
Or am I way off and it's something else?
I am basically just trying to figure out how to resolve a video encoder lockup during a GC loop. Any pointers or things to look for would be much appreciated. I've also noticed that the garbage collection (when it's happening) seems to be causing the frame to stutter briefly, so that's something I'm trying to resolve aswell.
Here's the full code base:
https://github.com/hexag0d/BitChute_Mobile_Android_BottomNav/blob/VideoPreProcessing_/PtOffsetRedux/VideoEncoding/OutputSurface.cs
Please advise
EDIT: I just noticed that the branch I posted had inherited from Java.Lang.Object on the OutputSurface class. I removed this and pushed the branch again. I have a bunch of branches trying to get this working and I had backtracked to a branch that still inherited from this class. I know that in many previous attempts I had removed all Java.Lang.Object inheritances from the project and it was still locking up on the GC.
UPDATE: When I run the code in the branch above, I don't see the GREFs going over 46k, but the video seems to still be locking up on the garbage collection; it's just that now the video processing will actually finish, and the GREF count is still getting really close to 46k. I think with a really long video it'd still get tipped over 46k, as the count continually goes up while the processing gets further through the video.
It turns out that all I had to do was comment out the line I had mentioned as being suspect:
var curDisplay = EGLContext.EGL.JavaCast<IEGL10>().EglGetCurrentDisplay();
It runs in a loop that gets called thousands of times for a complete video to finish.
What must have been happening is that these EGLDisplay instances (var) were not being properly garbage collected. I would have thought they'd get automatically collected when the method is finished, but something was stopping that from happening. If you know more about this feel free to give a better answer; I'm not exactly sure what caused the finalizer to get hung up on those objects.
That alone won't really do anyone very much in solving this type of problem, so here's how I figured it out:
first I added this code to the MainActivity OnCreate .. this writes the GREF logs to a file in the /download folder at the root of the droid device then loops and updates every 120 seconds (or whatever interval you choose)
#if DEBUG
Task.Run(async () =>
{
const int seconds = 120;
const string grefTag = "monodroid-gref";
const string grefsFile = "grefs.txt";
while (true)
{
var appDir = Application.ApplicationInfo.DataDir;
var grefFile = System.IO.Path.Combine("/data/data", PackageName, "files/.__override__", grefsFile);
var grefFilePublic = System.IO.Path.Combine(Android.OS.Environment.ExternalStorageDirectory + Java.IO.File.Separator + "download", grefsFile);
if (System.IO.File.Exists(grefFile))
{
System.IO.File.Copy(grefFile, grefFilePublic, true);
System.Console.Write(grefTag, $"adb pull {grefFilePublic} {grefsFile}");
}
else
System.Console.Write(grefTag, "no grefs.txt found, gref logging enabled? (adb shell setprop debug.mono.log gref)");
await Task.Delay(seconds * 1000);
}
});
#endif
Then run this command which enables the gref logging on the device
adb shell setprop debug.mono.log gref
Then I ran the app and let the video processor go and eventually bog down. After this, I collected the .txt file from the download folder and inspected using Visual Studio Code (because it handles large files easily)
In my case, there was a loop running over and over that looked like this, repeated thousands of times:
take_weak_global_ref_jni
-g- grefc 25196 gwrefc 7 handle 0x6495a/G from thread 'finalizer'(27691)
take_weak_global_ref_jni
*take_weak obj=0x7c1046df60; handle=0x64106
+w+ grefc 25195 gwrefc 8 obj-handle 0x64106/G -> new-handle 0x953/W from thread 'finalizer'(27691)
take_weak_global_ref_jni
-g- grefc 25195 gwrefc 8 handle 0x64106/G from thread 'finalizer'(27691)
take_weak_global_ref_jni
*take_weak obj=0x7c19c4e630; handle=0x64fd6
+w+ grefc 25194 gwrefc 9 obj-handle 0x64fd6/G -> new-handle 0x963/W from thread 'finalizer'(27691)
take_weak_global_ref_jni
-g- grefc 25194 gwrefc 9 handle 0x64fd6/G from thread 'finalizer'(27691)
take_weak_global_ref_jni
*take_weak obj=0x7c1046df98; handle=0x63d9a
+w+ grefc 25193 gwrefc 10 obj-handle 0x63d9a/G -> new-handle 0x973/W from thread 'finalizer'(27691)
take_weak_global_ref_jni
-g- grefc 25193 gwrefc 10 handle 0x63d9a/G from thread 'finalizer'(27691)
take_weak_global_ref_jni
I think these are the memory addresses that are stuck unable to be collected. Notice the handle=0x64fd6
So I did a search for that address in the .txt file and it led me to this:
+g+ grefc 25190 gwrefc 0 obj-handle 0x4eaba/I -> new-handle 0x64fd6/G from thread 'Thread Pool Worker'(8)
at Android.Runtime.AndroidObjectReferenceManager.CreateGlobalReference (Java.Interop.JniObjectReference value) [0x00000] in <016ee5efc3d0460baf9a60f95885ebbb>:0
at Java.Interop.JniObjectReference.NewGlobalRef () [0x00000] in <286213b9e14c442ba8d8d94cc9dbec8e>:0
at Android.Runtime.JNIEnv.NewGlobalRef (System.IntPtr jobject) [0x00000] in <016ee5efc3d0460baf9a60f95885ebbb>:0
at Java.Lang.Object.RegisterInstance (Android.Runtime.IJavaObject instance, System.IntPtr value, Android.Runtime.JniHandleOwnership transfer, System.IntPtr& handle) [0x00000] in <016ee5efc3d0460baf9a60f95885ebbb>:0
at Java.Lang.Object.SetHandle (System.IntPtr value, Android.Runtime.JniHandleOwnership transfer) [0x00000] in <016ee5efc3d0460baf9a60f95885ebbb>:0
at Java.Lang.Object..ctor (System.IntPtr handle, Android.Runtime.JniHandleOwnership transfer) [0x00000] in <016ee5efc3d0460baf9a60f95885ebbb>:0
at Javax.Microedition.Khronos.Egl.IEGL10Invoker..ctor (System.IntPtr handle, Android.Runtime.JniHandleOwnership transfer) [0x00000] in <016ee5efc3d0460baf9a60f95885ebbb>:0
at System.Reflection.MonoCMethod.InternalInvoke (System.Reflection.MonoCMethod , System.Object , System.Object[] , System.Exception& ) [0x00000] in <d4a23bbd2f544c30a48c44dd622ce09f>:0
at System.Reflection.MonoCMethod.InternalInvoke (System.Object obj, System.Object[] parameters, System.Boolean wrapExceptions) [0x00000] in <d4a23bbd2f544c30a48c44dd622ce09f>:0
at System.Reflection.MonoCMethod.DoInvoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <d4a23bbd2f544c30a48c44dd622ce09f>:0
at System.Reflection.MonoCMethod.Invoke (System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <d4a23bbd2f544c30a48c44dd622ce09f>:0
at System.Reflection.ConstructorInfo.Invoke (System.Object[] parameters) [0x00000] in <d4a23bbd2f544c30a48c44dd622ce09f>:0
at Java.Interop.TypeManager.CreateProxy (System.Type type, System.IntPtr handle, Android.Runtime.JniHandleOwnership transfer) [0x00000] in <016ee5efc3d0460baf9a60f95885ebbb>:0
at Java.Interop.TypeManager.CreateInstance (System.IntPtr handle, Android.Runtime.JniHandleOwnership transfer, System.Type targetType) [0x00000] in <016ee5efc3d0460baf9a60f95885ebbb>:0
at Java.Lang.Object.GetObject (System.IntPtr handle, Android.Runtime.JniHandleOwnership transfer, System.Type type) [0x00000] in <016ee5efc3d0460baf9a60f95885ebbb>:0
at Java.Interop.JavaObjectExtensions._JavaCast[TResult] (Android.Runtime.IJavaObject instance) [0x00000] in <016ee5efc3d0460baf9a60f95885ebbb>:0
at Java.Interop.JavaObjectExtensions.JavaCast[TResult] (Android.Runtime.IJavaObject instance) [0x00000] in <016ee5efc3d0460baf9a60f95885ebbb>:0
at Android.Runtime.Extensions.JavaCast[TResult] (Android.Runtime.IJavaObject instance) [0x00000] in <016ee5efc3d0460baf9a60f95885ebbb>:0
at MediaCodecHelper.OutputSurface.AwaitNewImage (System.Boolean returnOnFailure) [0x00079] in C:\repos\BitChute_Mobile_Android_BottomNav_newAppBak - Copy - Copy\VideoEncoding\OutputSurface.cs:298
at MediaCodecHelper.FileToMp4.EncodeFileToMp4 (System.String inputPath, System.String outputPath, System.Boolean encodeAudio, Android.Net.Uri inputUri) [0x00202] in C:\repos\BitChute_Mobile_Android_BottomNav_newAppBak - Copy - Copy\VideoEncoding\FileToMp4.cs:253
at MediaCodecHelper.FileToMp4.Start (Android.Net.Uri inputUri, System.String outputPath, System.String inputPath) [0x00007] in C:\repos\BitChute_Mobile_Android_BottomNav_newAppBak - Copy - Copy\VideoEncoding\FileToMp4.cs:181
at BitChute.Fragments.SettingsFrag+<>c.<StartEncoderTest>b__18_0 () [0x000fe] in C:\repos\BitChute_Mobile_Android_BottomNav_newAppBak - Copy - Copy\Fragments\SettingsFrag.cs:310
at System.Threading.Tasks.Task.InnerInvoke () [0x00000] in <d4a23bbd2f544c30a48c44dd622ce09f>:0
at System.Threading.Tasks.Task.Execute () [0x00000] in <d4a23bbd2f544c30a48c44dd622ce09f>:0
at System.Threading.Tasks.Task.ExecutionContextCallback (System.Object obj) [0x00000] in <d4a23bbd2f544c30a48c44dd622ce09f>:0
at System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) [0x00000] in <d4a23bbd2f544c30a48c44dd622ce09f>:0
at System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) [0x00000] in <d4a23bbd2f544c30a48c44dd622ce09f>:0
at System.Threading.Tasks.Task.ExecuteWithThreadLocal (System.Threading.Tasks.Task& currentTaskSlot) [0x00000] in <d4a23bbd2f544c30a48c44dd622ce09f>:0
at System.Threading.Tasks.Task.ExecuteEntry (System.Boolean bPreventDoubleExecution) [0x00000] in <d4a23bbd2f544c30a48c44dd622ce09f>:0
at System.Threading.Tasks.Task.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem () [0x00000] in <d4a23bbd2f544c30a48c44dd622ce09f>:0
at System.Threading.ThreadPoolWorkQueue.Dispatch () [0x00000] in <d4a23bbd2f544c30a48c44dd622ce09f>:0
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback () [0x00000] in <d4a23bbd2f544c30a48c44dd622ce09f>:0
handle 0x64fd6; key_handle 0x259aa25: Java Type: `com/google/android/gles_jni/EGLImpl`; MCW type: `Javax.Microedition.Khronos.Egl.IEGL10Invoker`
notice Javax.Microedition.Khronos.Egl.IEGL10Invoker and handle 0x64fd6
I recommend checking the memory handles in the part where your GC is getting stuck in a loop; then search for those handles and see if you can find the type that they are referencing. After you've found what type the loop is stuck trying to GC, you will need to back track through the source code and find a spot where this type is being called (or instantiated) in a loop. I think it's typically (from what I've read) loops that are generating undisposed Java.Lang.Object references which cause the GC to fail.
So I knew at that point it was something related to the interface IEGL10. I went back and tried just removing from the loop and it worked! GREFs never go above 600 now.
quick steps:
1. enable gref logging
2. run app
3. check logs for the memory addresses that are not being collected properly (where your app gets stuck in a GC loop, you'll likely see
a ton of repeated lines)
4. search for those memory addresses
5. check for the object **type** that is in the memory handle assignment stack trace
6. go back to your long running problematic loops and see if you can find a matching method being called or an object instantiation in rapid succession and not
being disposed of
7. either `Dispose` your looped objects manually or I also read to try and avoid `Java.Lang.Object` inheritance if it's in a long
running loop.
You likely won't be as lucky as me where I can just comment out a line of code. You'll probably have to figure out a way to dispose of the looped object manually or do something else to notify the app it can safely GC those objects, but the memory addresses should give you a clue as to which object is causing a problem with the GC.
I'm sorry if that isn't the greatest answer, but I'm not very familiar with how GC works. If anyone can give a better explanation I would be curious to hear more details on this, but that's how I fixed mine! Hope it helps

Windows service: using of BitmapEncoder or BitmapDecoder ends with «The operation completed successfully»

I am facing a problem that I am not able to solve or google solution anywhere.
I am running service that load or saves images and uses BitmapEncoder or BitmapDecoder classes. After some time (depending how often I save/load images) service refuse to save/load images. First I see warning in event log with
heap allocation failed
I googled what does it mean and it has to do with limited number of GDI objects that Windows service has. Its possible to modify registry to increase number of these object but its not very nice solution I think and also it does not work for me.
My code throws following exception with stack trace when saving
Error while storing image : System.ComponentModel.Win32Exception (0x80004005): The operation completed successfully
at MS.Win32.HwndWrapper..ctor(Int32 classStyle, Int32 style, Int32 exStyle, Int32 x, Int32 y, Int32 width, Int32 height, String name, IntPtr parent, HwndWrapperHook[] hooks)
at System.Windows.Threading.Dispatcher..ctor()
at System.Windows.Threading.DispatcherObject..ctor()
at System.Windows.Media.Imaging.BitmapEncoder..ctor(Boolean isBuiltIn)
at Imaging.TiffReadWrite.Save(String filename, Image img)
and when loading
Error while loading image : System.ComponentModel.Win32Exception (0x80004005): The operation completed successfully
at MS.Win32.HwndWrapper..ctor(Int32 classStyle, Int32 style, Int32 exStyle, Int32 x, Int32 y, Int32 width, Int32 height, String name, IntPtr parent, HwndWrapperHook[] hooks)
at System.Windows.Threading.Dispatcher..ctor()
at System.Windows.Threading.DispatcherObject..ctor()
at System.Windows.Media.Imaging.BitmapDecoder..ctor(Stream bitmapStream, BitmapCreateOptions createOptions, BitmapCacheOption cacheOption, Guid expectedClsId)
at Imaging.TiffReadWrite.Load(String filename)
My code for saving images looks like:
public static void Save(string filename, BitmapSource img)
{
using (FileStream stream = new FileStream(filename, FileMode.Create))
{
TiffBitmapEncoder encoder = new TiffBitmapEncoder();
encoder.Compression = TiffCompressOption.None;
BitmapFrame frm = BitmapFrame.Create(img);
encoder.Frames.Add(frm);
encoder.Save(stream);
}
}
and for loading images looks like:
public static BitmapSource Load(string filename)
{
BitmapSource resultImage = null;
using (Stream imSource = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read))
{
var decoder = new TiffBitmapDecoder(imSource, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
resultImage = decoder.Frames[0];
}
return resultImage;
}
So, service refuses to save/load images. I can try/catch this exception so the service can continue running, but no images could be saved/load. Sometimes after first occurrence of this exception few images could be saved/loaded and after a while no saving/loading is performed.
My only workaround for this problem is not running this code in service but in application. Then it runs just fine, but that is not a solution I am looking for. If anyone has any better suggestion please let me know.
There are some similar posts (stack trace of exception is more or less the same) that is not actually solved:
Image Resizing : The operation completed successfully
Does that mean an object doesn't need to be cleared manually if it doesn't implement IDisposable?
Windows.Media.Imaging Thumbnail generation causing exceptions
The operation completed successfully
This mystifying message narrows down the exact code in the HwndWrapper constructor that fails. WPF has a bug in the GetStockObject pinvoke declaration. Its SetLastError = true property is wrong, GetStockObject() does not in fact produces an error code. You see the description of error code 0, "nothing went wrong".
GetStockObject() is a winapi function that never fails if it gets the correct argument. Stock objects are pre-allocated and never released. You have very strong evidence that the process state is thoroughly corrupted. Seeing a "heap allocation failed" message in the event log is certainly part of that misery.
If you have no idea what could cause this corruption, machine is known-good with reliable RAM, you are not running any dangerous native code and the machine is not running any other services that could corrupt the desktop heap, then the only alternative you have is to create a minidump of the crashed process. Call Microsoft Support, they can follow the trace from the GetStockObject() failure. Do beware that you'll have to get through the first support layers, the ones that will tell you to swap the machine out :)

System.UnauthorizedAccessException when trying to accept audio call in Lync 2013

I have a problem with my Lync client that I am designing. I am running Lync 2013 in UI Suppression mode and I am able to send/receive IM's just fine, and begin audio calls. But a problem occurs when I try to receive an audio conversation from someone else. I get a System.UnauthorizedAccessException when I try to call this line of code:
conv.Modalities[ModalityTypes.AudioVideo].BeginConnect(ModalityCallback, asyncState);
It runs perfectly fine otherwise, and the call goes through okay and I can hear and talk to the other side just fine, but my User Interface freezes and I can't control anything due to this error. Even when the other side hangs up, I have to kill the process in Task Manager.
Here is my InitiateAVStream method, based on the MSDN Join Lync conversation example:
public bool InitiateAVStream()
{
Console.WriteLine("InitiateAVStream");
if (conv.State == ConversationState.Terminated)
{
return false;
}
if (conv.Modalities[ModalityTypes.AudioVideo].CanInvoke(ModalityAction.Connect))
{
conv.Modalities[ModalityTypes.AudioVideo].ModalityStateChanged += _AVModality_ModalityStateChanged;
conv.Modalities[ModalityTypes.AudioVideo].ActionAvailabilityChanged += _AVModality_ActionAvailabilityChanged;
//Accept the notification. If Lync UI is enabled, incoming call notification is closed.
conv.Modalities[ModalityTypes.AudioVideo].Accept();
//Connect the AV modality and begin to send and received AV stream.
object[] asyncState = { conv.Modalities[ModalityTypes.AudioVideo], "CONNECT" };
try
{
conv.Modalities[ModalityTypes.AudioVideo].BeginConnect(ModalityCallback, asyncState);
}
catch (Exception ex)
{
Console.WriteLine(ex.StackTrace);
}
return true;
}
return false;
}
The output message:
A first chance exception of type 'System.UnauthorizedAccessException' occurred in Microsoft.Lync.Model.dll
at Microsoft.Office.Uc.ModalityClass.Connect(ModalityConnectOptions _options, Object _modalityCallback, Object _state)
at Microsoft.Lync.Model.Conversation.Modality.BeginConnect_private(ModalityConnectOptions options, AsyncCallback modalityCallback, Object state)
at Microsoft.Lync.Model.Conversation.Modality.BeginConnect(AsyncCallback modalityCallback, Object state)
at UIPrototype.MeetingForm.InitiateAVStream() in c:\Users\morrissi\Documents\Visual Studio 2012\Projects\UIPrototype\UIPrototype\MeetingForm.cs:line 758
Any input would be greatly appreciated. And it's strange to me that it only occurs when I try accepting an incoming audio call. Everything else works fine. I have not started work on video calls yet, but I will once I get audio working.
Thanks
Edit:
Replacing BeginConnect with BeginRetrieve still throws the same error and produces the same results. Still not sure what to do.
Where are you running your application from? I had a very similar stacktrace and moving the application into "C:\Users\MyUser" resolved the problem for me.
I was able to solve the problem. Apparently when you are connecting just an audio call, the only line you need is
conv.Modalities[ModalityTypes.AudioVideo].Accept();
You do not need to call BeginConnect to connect the audio. Removing BeginConnect prevents the error from being thrown and the audio connects just fine still. BeginConnect is used to connect video.
My problem with the form not loading completely and freezing is unrelated, it appears. That is being caused because I am trying to create a new form within ConversationManager_ConversationAdded. If I try creating a new form on a button click, it loads just fine and works, but it seems to be the event that is preventing it from working properly.
I'm not good enough at this to recognize when an error is being caused by Lync or C# yet.

Categories

Resources