My DLL application creates a new class in an exported function when it gets called. The class constructor creates a new thread. After calling detach() the main thread does NOT continue and the entire application hangs.
In class constructor:
spawn().detach();
private member function:
std::thread spawn() {
return std::thread([=] { WriteProcess(false); });
}
WriteProcess:
for (;; std::this_thread::sleep_for(std::chrono::milliseconds(LOG_THREAD_TICK_RATE)))
{
// does stuff
}
Omitting lambdas for creating a thread does not solve it.
Using CreateThread this issue does not occur and WriteProcess works as expected.
I am using VS2013 C++11 on Windows 8 and I'm currently not able to debug the process where my dll gets loaded into.
Related
I recently ran into this error. I have never came across this before so wondering!
Cannot access a disposed context instance. A common cause of this error is disposing a context instance that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling 'Dispose' on the context instance, or wrapping it in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances.
Object name: 'OrderDbContext'.
The only thing i missed which produced this error is the await keyword in the controller action method before _mediator.Send(checkoutCommand); Once I added the await keyword this error vanished.
What (the heck) is wrong with missing this await keyword? The error does not explicitly state that. Can someone explain why missing an await keyword cause an error that database context is disposed?
Controller Action:
public async Task<IActionResult> Checkout(CheckoutOrderCommand checkoutCommand)
{
**var id = _mediator.Send(checkoutCommand);**
return CreatedAtRoute("Get Order by Id", id);
}
CQRS Mediatr Instructions
public class CheckoutOrderCommandHandler : IRequestHandler<CheckoutOrderCommand, int>
{
private readonly IOrderUow _orderUow;
private readonly IMapper _mapper;
public CheckoutOrderCommandHandler(IOrderUow orderUow,
IMapper mapper)
{
_orderUow = orderUow;
_mapper = mapper;
}
public async Task<int> Handle(CheckoutOrderCommand request, CancellationToken cancellationToken)
{
var order = _mapper.Map<Order>(request);
// Populate base entity fields
order.CreatedBy = Constants.CurrentUser;
// create new order
var newOrder = await _orderUow.AddOrderAsync(order);
return newOrder.Id;
}
}
Unit of work implementation
public class OrderUow : IOrderUow
{
private readonly OrderDbContext _orderContext;
public OrderUow(OrderDbContext orderContext)
{
_orderContext = orderContext;
}
public async Task<Order> AddOrderAsync(Order order)
{
try
{
await _orderContext.Orders.AddAsync(order);
await _orderContext.SaveChangesAsync();
}
catch (Exception ex)
{
}
return order;
}
}
Missing an await without explicitly handling the task that is returned will mean that the code calling the asynchronous method will not create a resumption point and instead will continue executing to completion, in your case leading to the disposal of the DbContext.
Asyncrhronous code is multi-threaded behind the scenes. Think of it this way, your web request enters on Thread #1 which creates a DbContext instance via an IoC container, calls an asynchronous method, then returns. When the code calls an async method, it automatically hands that code off to a worker thread to execute. By adding await you tell .Net to create a resume point to come back to. That may be the original calling thread, or a new worker thread, though the important thing is that the calling code will resume only after the async method completes. Without await, there is no resume point, so the calling code continues after the async method call. This can lead to all kinds of bad behaviour. The calling code can end up completing and disposing the DbContext (what you are seeing) or if it calls another operation against the DbContext you could end up with an exception complaining about access across multiple threads since a DbContext detects that and does not allow access across threads.
You can observe the threading behaviour by inspecting Thread.CurrentThread.ManagedThreadId before the async method call, inside the async method, then after the async method call.
Without the await you would see Thread #X before the method call, then Thread #Y inside the async method, then back to Thread #X after. While debugging it would most likely appear to work since the worker thread would likely finish by the time you were done with the breakpoints, but at runtime that worker thread (Y) would have been started, but the code after the call on thread X would continue running, ultimately disposing of your DbContext likely before Thread Y was finished executing. With the await call, you would likely see Thread #X before the method call, Thread #Y inside, then Thread #Z after the call. The breakpoint after the async call would only be triggered after the async method completes. Thread #X would be released while waiting for the async method, but the DbContext etc. wouldn't be disposed until the resumption point created by awaiting the async method had run. It is possible that the code can resume on the original thread (X) if that thread is available in the pool.
This is a very good reason to follow the general naming convention for asynchronous methods to use the "Async" suffix for the method name. If your Mediator.Send method is async, consider naming it "SendAsync" to make missing await statements a lot more obvious. Also check those compiler warnings! If your project has a lot of warnings that are being ignored, this is a good reason to go through and clean them up so new warnings like this can be spotted quickly and fixed. This is one of the first things I do when starting with a new client is look at how many warnings the team has been ignoring and pointing out some of the nasty ones they weren't aware were lurking in the code base hidden by the noise.
I have a suspend function that calls POST request to the server. I want to configure some text in the activity to show the information I received from the server.
suspend fun retrieveInfo():String
I tried calling inside onCreate, onResume but crashes runtime.
runBlocking {
retrieveInfo()
}
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.google.augmentedimage/com.google.AugmentedImageActivity}: android.os.NetworkOnMainThreadException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3086)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3229)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
Where am I suppose to put these suspend calls (in which part of lifecycle of activity)? Should I be using something other than runBlocking?
By default runBlocking runs the suspending code block in the thread runBlocking was called on.
So if you called runBlocking from the Activity callback your suspending block will be executed on the main thread, from which you cannot access network (query a server).
You need to switch a dispatcher in your coroutine block for that call. The simplest fix for your code would be to move the execution to the Dispatchers.IO.
runBlocking {
withContext(Dispatchers.IO) {
retrieveInfo()
}
}
That being said, I suggest two things (not related directly to your question):
Read Coroutines on Android (this part and the following ones)
2. Don't use runBlocking for your case, but define a correct job and use job.launch{}
If you want to write in activity:
class MyActivity : AppCompatActivity() {
private val scope = CoroutineScope(newSingleThreadContext("name"))
fun doSomething() {
scope.launch { ... }
}
}
My code looks like this:
public void Init() {
if (AS.pti == PTI.UserInput)
{
AS.runCardTimer = false;
}
else
{
AS.runCardTimer = true;
Device.BeginInvokeOnMainThread(() => showCards().ContinueWith((arg) => { }));
}
}
The Init method is called from the constructor. Can someone please explain to me why the developer might have added the Device.BeginInvokeOnMainThread() instead of just calling the method showCards?
Also what does the ContinueWith((arg)) do and why would that be included?
The class where this Init() method is might be created on a background thread. I'm assuming showCards() are updating some kind of UI. UI can only be updated on the UI/Main thread. Device.BeginInvokeOnMainThread() ensures that the code inside the lambda is executed on the main thread.
ContinueWith() is a method which can be found on Task. If showCards() returns a task, ContinueWith() makes sure the task will complete before exiting the lambda.
UI actions must be performed on UI thread (different name for main thread). If you try to perform UI changes from non main thread, your application will crash. I think developer wanted to make sure it will work as intended.
The simple answer is: Background thread cannot modify UI elements because most UI operations in iOS and Android are not thread-safe; therefore, you need to invoke UI thread to execute the code that modifies UI such MyLabel.Text="New Text".
The detailed answer can be found in Xamarin document:
For iOS:
IOSPlatformServices.BeginInvokeOnMainThread() Method simply calls NSRunLoop.Main.BeginInvokeOnMainThread
public void BeginInvokeOnMainThread(Action action)
{
NSRunLoop.Main.BeginInvokeOnMainThread(action.Invoke);
}
https://developer.xamarin.com/api/member/Foundation.NSObject.BeginInvokeOnMainThread/p/ObjCRuntime.Selector/Foundation.NSObject/
You use this method from a thread to invoke the code in the specified object that is exposed with the specified selector in the UI thread. This is required for most operations that affect UIKit or AppKit as neither one of those APIs is thread safe.
The code is executed when the main thread goes back to its main loop for processing events.
For Android:
Many People think on Xamarin.Android BeginInvokeOnMainThread() method use Activity.runOnUiThread(), BUT this is NOT the case, and there is a difference between using runOnUiThread() and Handler.Post():
public final void runOnUiThread(Runnable action) {
if (Thread.currentThread() != mUiThread) {
mHandler.post(action);//<-- post message delays action until UI thread is scheduled to handle messages
} else {
action.run();//<--action is executed immediately if current running thread is UI thread.
}
}
The actual implementation of Xamarin.Android BeginInvokeOnMainThread() method can be found in AndroidPlatformServices.cs class
public void BeginInvokeOnMainThread(Action action)
{
if (s_handler == null || s_handler.Looper != Looper.MainLooper)
{
s_handler = new Handler(Looper.MainLooper);
}
s_handler.Post(action);
}
https://developer.android.com/reference/android/os/Handler.html#post(java.lang.Runnable)
As you can see, you action code is not executed immediately by Handler.Post(action). It is added to the Looper's message queue, and is handled when the UI thread's scheduled to handle its message.
I am developing an app using Xamarin Android which has a WebView displaying a web page. I want to implement a two way communication between Javascript from WebView to c#. I could call C# from Javascript using this link. However i couldn't find a way to send data back from C# to Javascript.
Is there a way to send data back and forth in this approach. I thought writing a callback in Javascript would work but how to fire it from C# code.
Now, My problem is how to call WebView from a javascript interface class. I have a Javascript interface class as mentioned https://developer.xamarin.com/recipes/android/controls/webview/call_csharp_from_javascript/
namespace ScannerAndroid
{
public class JSInterface: Java.Lang.Object
{
Context context;
WebView webView;
public JSInterface (Context context, WebView webView1)
{
this.context = context;
this.webView = webView1;
}
[Export]
[JavascriptInterface]
public void ShowToast()
{
Toast.MakeText (context, "Hello from C#", ToastLength.Short).Show ();
this.webView.LoadUrl ("javascript:callback('Hello from Android Native');");
}
}
}
The code throws an exception at LoadUrl line. java.lang.Throwable: A WebView method was called on thread 'Thread-891'. All WebView methods must be called on the same thread. (Expected Looper Looper (main, tid 1) {42ce58a0} called on null, FYI main Looper is Looper (main, tid 1) {42ce58a0})
Now i am struggling how to refer the WebView from this Java script interface class
Yes. That is possible. If you are targeting KitKat or higher you can use:
webView.EvaluateJavascript("enable();", null);
Where in this case enable(); is a JS function.
If you are targeting lower API levels you can use LoadUrl();:
webView.LoadUrl("javascript:enable();");
EDIT:
The error you get where it complains on LoadUrl is because it for some reason happens on a non-UI thread.
Since you have already passed on the Context into your JavascriptInterface class, then you can simply wrap the contents of ShowToast in:
context.RunOnUiThread(() => {
// stuff here
});
Just change signature from Context to Activity and it should help you marshal you back on UI thread.
So, what happened in my project was the following:
I have a singleton which is defined in a usual way:
Singleton* Singleton::getInstance()
{
static Singleton instance;
return &instance;
}
in its constructor, this singleton object initializes a CORBA ORB and started running it in a separate (boost)thread(wrapper) similar to this:
CorbaController::CorbaController()
{
}
CorbaController::~CorbaController()
{
if(!CORBA::is_nil(_orb))
_orb->shutdown(true);
}
void CorbaController::run()
{
_orb->run();
}
bool CorbaController::initCorba(const std::string& ip, unsigned long port)
{
// init CORBA
// ...
// let the ORB execute in a dedicated thread since the run operation is blocking
start();
return true;
}
Now the normal behavior when destructing the CorbaController is that it calls shutdown on the ORB in its destructor, the run method then jumps out of orb.run() and finishes the separate thread. However this only works if the CorbaController is deleted explicitly or defined as a local or class variable which then runs out of scope at some point.
If I rely on the singleton's static variable being cleaned up at the end of the program though, the orb.shutdown() deadlocks because the ACE/TAO lib can't aquire a semaphore on some object to be destructed with the ORB shutdown.
Does anybody have an idea of what might be the problem here? Can this be a threading problem, i.e. that the thread which constructrs the singleton (and also runs the main function of my application) is different from the thread cleaning up static memory instances?
You have to shuytdown and destroy the ORB during the regular shutdown of the application, doing it in the destructor of a static object is really too late. Add a shutdown() method to your CORBA Controller which does a shutdown and destroy of the ORB.