MethodAccessException on Task.CompletedTask property - c#

I am working on a small wpf application and one of the users is getting the following exception:
System.MethodAccessException:
Attempt by method "xxx.HttpConfirmation.Invoke()" to access method "System.Threading.Tasks.Task.get_CompletedTask()" failed.
at xxx.HttpConfirmation.Invoke()
at xxx.RequestPipeline.<ProcessQueuedRequests>d__11.MoveNext()
According to MSDN documentation, such exception is thrown in the following situations:
A private, protected, or internal method that would not be accessible from normal compiled code is accessed from partially trusted code by using reflection.
A security-critical method is accessed from transparent code.
The access level of a method in a class library has changed, and one or more assemblies that reference the library have not been recompiled.
Task.get_CompletedTask() is public since its introduction and I am also not using reflection to access the property.
I also don't think that there is a problem with code security/transparency since only one user is having this issue.
The exception is thrown at the Task.CompletedTask line:
public class HttpConfirmation
{
public static Task Invoke()
{
using (var client = new WebClient())
{
try
{
// Send the request and don't wait for the response.
client.UploadStringTaskAsync("http://sampleUrl.com", string.Empty);
}
catch
{
// ignore
}
}
return Task.CompletedTask;
}
}
Any ideas on what may cause the exception?

The problem was that the customer had .NET 4.5.2 installed and the program targeted .NET 4.6.
Though I still have no clue as to why exactly System.MethodAccessException was thrown as none of the 3 documented situations for throwing this exception did happen.

Related

Win2D APIs fail randomly with error "Objects used together must be created from the same factory instance."

I am writing a UWP app with extensive use of Win2D APIs.
Sometimes, with no defined pattern, nor possibility to reproduce the behavior systematically, an un-caught exception of type System.Exception {System.Runtime.InteropServices.COMException} is raised by the framework, with no stack trace and only the following message:
Error HRESULT E_FAIL has been returned from a call to a COM component.
and a slightly more useful description
Objects used together must be created from the same factory instance.
Since there is no stack trace, I am not able to understand what is the cause of such exception, nor the piece of code that produces it.
According to the description, I tried to use a single factory for every Win2D operation, and specifically, I collected into 3 public static variables the factories I use:
public static class Win2DUtils
{
public static readonly Compositor Compositor = Window.Current.Compositor;
public static readonly CanvasDevice CanvasDev = CanvasDevice.GetSharedDevice();
public static readonly CompositionGraphicsDevice GraphicsDevice = CanvasComposition.CreateCompositionGraphicsDevice(Compositor, CanvasDev);
}
Even with this escamotage, I am still experiencing the issue.
I also tried in Visual Studio to flag all the possible Exception to stop the execution when they are raised, but if with this setting the Exception is completely un-caught, and can only be perceived thanks to the builtin exception handling of Visual Studio in Debug mode (the code in App.g.i.cs that is automatically added by the scaffolding of Visual Studio in every UWP project, something like:
#if DEBUG && !DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION
UnhandledException += (sender, e) =>
{
if (global::System.Diagnostics.Debugger.IsAttached) global::System.Diagnostics.Debugger.Break();
};
#endif
Is anybody aware of what could be the possible cause and at least how to catch the source of the exception?
Thank you very much
cghersi
I had similar error, but it crash only on some devices(all of them was with Intel HD Graphics). The reason was I forgot to remove CanvasDevice.DebugLevel = CanvasDebugLevel.Information;
if (CanvasDevice != null)
{
CanvasDevice.DeviceLost -= CanvasDeviceOnDeviceLost;
}
CanvasDevice.DebugLevel = CanvasDebugLevel.Information;//Remove this on release. On some devices cause app crash
CanvasDevice = CanvasDevice.GetSharedDevice();
//error:Canvas.GetSharedDevice Error HRESULT E_FAIL has been returned from a call to a COM component.
I finally solved the issue (apparently) so I post for anybody else that hits the same problem.
In our code we are instantiating a CanvasAnimatedControl to draw some ink.
By default, the public parameter-less constructor of CanvasAnimatedControl sets the flag UseSharedDevice to false, which allows the CanvasAnimatedControl to create its own CanvasDevice.
Creating the canvas as:
aniCanvas = new CanvasAnimatedControl()
{
UseSharedDevice = true
};
solved the problem and the exception doesn't show up anymore.

Void MoveNext() in Null reference exception

I have a WebAPI which is having the following piece of code in which there is Null reference exception in the code written in try block which is getting logged using my logger.
But in the TargetSite of the Exception getting logged, I am receiving Void MoveNext() instead of the method name in which this code is written.
What could be the reason for the same??
public async Task<ResponseStatus> ProcessRCSCNotification(IList<RecurringSubscriptionModelV2> recurringSubscriptionList, string appCD)
{
foreach (var model in modelList)
{
// Some code
try
{
// Exception occurs here
}
catch (Exception ex)
{
// Logger is logging exception here
}
}
return null;
}
You have an async method with several awaits. The compiler transform this whole method into a state machine and your method ends up actually only calling this state machine.
This state machine class has the mentioned MoveNext() method that now contains all the work you actually wanted to do.
To analyze your NullReferenceException you should rather check the StackTrace property of the exception than the TargetSite.
The method is an async/await method.
This kind of method is rewritten to a state machine with a MoveNext method. That's why your stack trace will identify this method as the one throwing that exception.
.NET Core 2.0 or 2.1 have either built-in or an extra nuget package that will fix stack traces like this to mention the actual method instead of the generated one.
You can read more about this here: Age of Ascent: Stacktrace improvements in .NET Core 2.1.
It might not fixup the TargetSite however, and I don't think it will handle .NET Framework.

InvalidOperationException in my Lazy<> value factory

I have a class containing something like the following:
public static class Config
{
private static Lazy<ConfigSource> _cfgSrc = new Lazy<ConfigSource>(
() => { /* "ValueFactory" here... */ },
true);
public static ConfigSource ConfigSource
{
get { return _cfgSrc.Value; }
}
}
In accessing the ConfigSource property, I encountered this InvalidOperationException:
ValueFactory attempted to access the Value property of this instance.
I don't see anything in my "value factory" method that accesses the Value property. Is there anything else that could be triggering this exception? This problem only happens intermittently, but once it does, it takes resetting IIS to clear up the Exception (which appears to be cached once it occurs).
It turned out that this error only occurred when trying to inspect the Value property of the Lazy<> in the Visual Studio debugger. Doing so appeared to create a deadlock because the accessing of Value then seemed to hang the thread for a long time until the InvalidOperationException finally occurred. I could never intercept the original Exception, so I couldn't see the inner stacktrace.
I'm just chalking this up as a bug in Visual Studio or their implementation of Lazy<>.
This has also happened to me with circular dependencies, so if these steps lead you nowhere, try double checking the stacktrace and verifying that there are no circular dependencies.
ValueFactory attempted to access the Value property of this instance.
It may help somebody, I was able to fix that error by inspecting my entire ValueFactory procedure.
In my example, I was creating a simple model and the linked it with some other data but during the linking process I was accessing the Value property in a singleton and that caused the error.
So accessing the Value of a Lazy object inside the ValueFactory throws such an error.
As the error message is already indicating ;-)
The behavior of Lazy<T> is to cache exceptions thrown by the ValueFactory. This can lead to potentially confusing behavior due to the paucity of information given in the InvalidOperationException message. Microsoft was made aware of this issue through Connect, however, it is marked as Wont Fix as they feel there is enough information in the exception itself to diagnose the problem.
If there is an inner exception for the IOE you receive, it should (not saying it will) contain enough information to continue onwards. Another possibility is you have a try...catch blocks which rethrows exceptions (throw ex; instead of throw;), you will lose valuable information.
To make sure your exception isn't cached, use LazyThreadSafetyMode.PublicationOnly as a second parameter, instead of true.
Using true, you'll end up with a LazyThreadSafetyMode.ExecutionAndPublication. This will ensure only one thread enteres the ValueFactory method, but also ensures exceptions will be cached.
private static Lazy<ConfigSource> _cfgSrc = new Lazy<ConfigSource>(
() => { /* "ValueFactory" here... */ },
LazyThreadSafetyMode.PublicationOnly);
See the link sixlettervariables provided for more information.
When lazy loading a configuration, be sure to not call methods that need said configuration. This will recall the configuration loader which starts over the process, resulting in the described error.
In my case, I was logging the loadstate, while the logger required a configuration

Uniformly handling error codes in an unmanaged API

I'm writing a wrapper around a fairly large unmanaged API. Almost every imported method returns a common error code when it fails. For now, I'm doing this:
ErrorCode result = Api.Method();
if (result != ErrorCode.SUCCESS) {
throw Helper.ErrorToException(result);
}
This works fine. The problem is, I have so many unmanaged method calls that this gets extremely frustrating and repetitive. So, I tried switching to this:
public static void ApiCall(Func<ErrorCode> apiMethod) {
ErrorCode result = apiMethod();
if (result != ErrorCode.SUCCESS) {
throw Helper.ErrorToException(result);
}
}
Which allows me to cut down all of those calls to one line:
Helper.ApiCall(() => Api.Method());
There are two immediate problems with this, however. First, if my unmanaged method makes use of out parameters, I have to initialize the local variables first because the method call is actually in a delegate. I would like to be able to simply declare a out destination without initializing it.
Second, if an exception is thrown, I really have no idea where it came from. The debugger jumps into the ApiCall method and the stack trace only shows the method that contains the call to ApiCall rather than the delegate itself. Since I could have many API calls in a single method, this makes debugging difficult.
I then thought about using PostSharp to wrap all of the unmanaged calls with the error code check, but I'm not sure how that would be done with extern methods. If it ends up simply creating a wrapper method for each of them, then I would have the same exception problem as with the ApiCall method, right? Plus, how would the debugger know how to show me the site of the thrown exception in my code if it only exists in the compiled assembly?
Next, I tried implementing a custom marshaler that would intercept the return value of the API calls and check the error code there. Unfortunately, you can't apply a custom marshaler to return values. But I think that would have been a really clean solution it if had worked.
[return:
MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(ApiMethod))]
public static extern ErrorCode Method();
Now I'm completely out of ideas. What are some other ways that I could handle this?
Follow ErrorHandler class from the Visual Studio 2010 SDK. It existed in earlier versions, but the new one has CallWithCOMConvention(Action), which may prove valuable depending on how your API interacts with other managed code.
Of the available methods, I recommend implementing the following:
Succeeded(int)
(Failed() is just !Succeeded(), so you can skip it)
ThrowOnFailure(int)
(Throws a proper exception for your return code)
CallWith_MyErrorCode_Convention(Action) and CallWith_MyErrorCode_Convention(Func<int>)
(like CallWithCOMConvention, but for your error codes)
IsCriticalException(Exception)
(used by CallWith_MyErrorCode_Convention)
What happens if you don't check ErrorCode.SUCCESS? Will your code quickly fail and throw an exception? Can you tell which unmanaged API failed if your managed code throws? If so, consider not checking for errors and just letting the runtime throw when your unmanaged API fails.
If this is not the case, I suggest biting the bullet and following your first idea. I know you called it "frustrating and repetitive", but after coming from a project with a "clever" macro solution to a similar problem, checking return values in method calls and wrapping exceptions is the doorway to insanity: exception messages and stack traces become misleading, you can't trace the code, performance suffers, your code become optimized for errors and goes off the rails upon success.
If a particular return value is an error, thow a unique exception then. If it might not be an error, let it go and throw if becomes an error. You said you wanted to reduce the check to one line?
if (Api.Method() != ErrorCode.SUCCESS) throw new MyWrapperException("Api.Method broke because ...");
Your proposal also throws the same exception if any method returns the same "common error code". This is another debugging nightmare; for APIs which return the same error codes from multiple calls, do this:
switch (int returnValue = Api.Method1())
{
case ErrorCode.SUCCESS: break;
case ErrorCode.TIMEOUT: throw new MyWrapperException("Api.Method1 timed out in situation 1.");
case ErrorCode.MOONPHASE: throw new MyWrapperException("Api.Method1 broke because of the moon's phase.");
default: throw new MyWrapperException(string.Format("Api.Method1 returned {0}.", returnValue));
}
switch (int returnValue = Api.Method2())
{
case ErrorCode.SUCCESS: break;
case ErrorCode.TIMEOUT: throw new MyWrapperException("Api.Method2 timed out in situation 2, which is different from situation 1.");
case ErrorCode.MONDAY: throw new MyWrapperException("Api.Method2 broke because of Mondays.");
default: throw new MyWrapperException(string.Format("Api.Method2 returned {0}.", returnValue));
}
Verbose? Yup. Frustrating? No, what's frustrating is trying to debug an app that throws the same exception from every line whatever the error.
I think, the easy way is to add aditional layer.
class Api
{
....
private static ErrorCode Method();//changing Method to private
public static void NewMethod()//NewMetod is void, because error is converted to exceptions
{
ErrorCode result = Method();
if (result != ErrorCode.SUCCESS) {
throw Helper.ErrorToException(result);
}
}
....
}
Create a private property to hold the ErrorCode value, and throw the exception from the setter.
class Api
{
private static ErrorCode _result;
private static ErrorCode Result
{
get { return _result; }
set
{
_result = value;
if (_result != ErrorCode.SUCCESS)
{
throw Helper.ErrorToException(_result);
}
}
}
public static void NewMethod()
{
Result = Api.Method();
Result = Api.Method2();
}
}
Write a T4 template to do the generation for you.
Your existing code is actually really, really close. If you use an expression tree to hold the lambda, instead of a Func delegate, then your Helper.ApiCall can pull out the identity of the function that was called and add that to the exception it throws. For more information on expression trees and some very good examples, Google Marc Gravell.

Throwing multiple exceptions in .Net/C#

In an application I work on, any business logic error causes an exception to be thrown, and the calling code handles the exception. This pattern is used throughout the application and works well.
I have a situation where I will be attempting to execute a number of business tasks from inside the business layer. The requirement for this is that a failure of one task should not cause the process to terminate. Other tasks should still be able to execute. In other words, this is not an atomic operation. The problem I have is that at the end of the operation, I wish to notify the calling code that an exception or exceptions did occur by throwing an exception. Consider the following psuedo-code snippet:
function DoTasks(MyTask[] taskList)
{
foreach(MyTask task in taskList)
{
try
{
DoTask(task);
}
catch(Exception ex)
{
log.add(ex);
}
}
//I want to throw something here if any exception occurred
}
What do I throw? I have encountered this pattern before in my career. In the past I have kept a list of all exceptions, then thrown an exception that contains all the caught exceptions. This doesn't seem like the most elegant approach. Its important to preserve as many details as possible from each exception to present to the calling code.
Thoughts?
Edit: The solution must be written in .Net 3.5. I cannot use any beta libraries, or the AggregateException in .Net 4.0 as mentioned by Bradley Grainger (below) would be a nice solution for collection exceptions to throw.
The Task Parallel Library extensions for .NET (which will become part of .NET 4.0) follow the pattern suggested in other answers: collecting all exceptions that have been thrown into an AggregateException class.
By always throwing the same type (whether there is one exception from the child work, or many), the calling code that handles the exception is easier to write.
In the .NET 4.0 CTP, AggregateException has a public constructor (that takes IEnumerable<Exception>); it may be a good choice for your application.
If you're targeting .NET 3.5, consider cloning the parts of the System.Threading.AggregateException class that you need in your own code, e.g., some of the constructors and the InnerExceptions property. (You can place your clone in the System.Threading namespace inside your assembly, which could cause confusion if you exposed it publicly, but will make upgrading to 4.0 easier later on.) When .NET 4.0 is released, you should be able to “upgrade” to the Framework type by deleting the source file containing your clone from your project, changing the project to target the new framework version, and rebuilding. Of course, if you do this, you need to carefully track changes to this class as Microsoft releases new CTPs, so that your code doesn't become incompatible. (For example, this seems like a useful general-purpose class, and they could move it from System.Threading to System.) In the worst case, you can just rename the type and move it back into your own namespace (this is very easy with most refactoring tools).
Two ways of the top of my head would be either make a custom exception and add the exceptions to this class and throw that the end :
public class TaskExceptionList : Exception
{
public List<Exception> TaskExceptions { get; set; }
public TaskExceptionList()
{
TaskExceptions = new List<Exception>();
}
}
public void DoTasks(MyTask[] taskList)
{
TaskExceptionList log = new TaskExceptionList();
foreach (MyTask task in taskList)
{
try
{
DoTask(task);
}
catch (Exception ex)
{
log.TaskExceptions.Add(ex);
}
}
if (log.TaskExceptions.Count > 0)
{
throw log;
}
}
or return true or false if the tasks failed and have a 'out List' variable.
public bool TryDoTasks(MyTask[] taskList, out List<Exception> exceptions)
{
exceptions = new List<Exception>();
foreach (MyTask task in taskList)
{
try
{
DoTask(task);
}
catch (Exception ex)
{
exceptions.Add(ex);
}
}
if (exceptions.Count > 0)
{
return false;
}
else
{
exceptions = null;
return true;
}
}
You could create a custom Exception that itself has a collection of Exceptions. Then, in your Catch block, just add it to that collection. At the end of your process, check if the Exception count is > 0, then throw your custom Exception.
You might want to use a BackgroundWorker to do this for you. It automatically captures and presents any exceptions when completed, which you could then throw or log or do whatever with. Also, you get the benefit of multithreading.
The BackgroundWorker is a nice wrapper around delegate's asynchronous programming model.
No super-elegant solution here but a few ideas:
Pass an error-handler function as argument to DoTasks so the user can decide whether to continue
Use tracing to log errors as they occur
Concatenate the messages from the other exceptions in the exception bundle's message

Categories