MVC background process preventing navigation to other pages while running - c#

I have an app that launches a long update on the backend (Dynamics 365 in this case). I want to launch it in the background while the user can continue doing things.
The problem is that while this task is running, the other pages don't load when I click on them. Maybe is the usual behavior.
Tried with Task.Run() HostingEnvironment.QueueBackgroundWorkItem() and the result is the same.
This is how my controller looks like:
public ActionResult ConfirmCurrentMonthMeetings() {
//Task.Factory.StartNew(() => QueryHelper.MarkReadOnlyCurrentMonthMeetings(guide.Id, svc));
HostingEnvironment.QueueBackgroundWorkItem(clt => QueryHelper.MarkReadOnlyCurrentMonthMeetings(guide.Id, svc));
ViewBag.ConfirmingMeetingsMessage = "Meetings being confirmed on the background. This action might take a few minutes";
PrepareMainScreen();
return View("MainScreen");
}

Apparently the variable svc that I use to perform the queries to the CRM is a shared resource and cannot be used while it's in use. I defined a second one and worked fine.

Related

Basic Auth in .NET with Filter & Async MongoDB comparison Task.wait() never ends

I have a REST API with an Basic Filter. The Filter checks against the DB (mongodb) before the actual request is made, wether the user is authorized. however this only works for the first time, afterwards it always gets stuck at
var filter = Builders<User>.Filter.Eq("email", email);
return _collection.Find(filter).FirstOrDefaultAsync();
which basically looks up the user in the DB based on the Email. The task doesn't finish and neither does it throw a timeout exception .
My question is somewhat related to this : C# Mongo FirstOrDefaultAsync hangs
however their fix didn't do it for me. I can't just keep passing the async tasks up the call hierarchy because at some point the filter expects a sychronous action based on the results. and an await doesnt cut it either.
Any ideas? I can't be the 1st one building a REST API with Basic Auth and a MongoDB behind it...
Help would be appreciated:)
Update:
a call like this also results in problems:
//...
await fbUserRepo.UpdateAsync(user);
//the method
public async Task<Guid> UpdateAsync(TEntity entity) {
entity.lastUpdatedTimestamp = DateTime.Now;
var filter = Builders<TEntity>.Filter.Eq("_id", entity.Id);
await _collection.ReplaceOneAsync(filter, entity);
return entity.Id;
}
when this method is called, nothing happens, nothing is returned.. its just stuck later at a .Wait() ... I haven't changed anything on my configuration and it happens both locally as well as in the azure cloud. performing queries directly on the mongodb is no problem, there are also no currentOp() pending. Also no timeout is thrown. its just like my application decided not to do anything anymore. the thread just stays still
Update again
The odd part is: I can CRUD all sorts of stuff into the DB. Only when I come from my AuthenticationFilter is where I get this trouble. I crawled over a 100k documents from FB and dropped then into my DB, updated them, etc. But fetching and updating my User Documents through my BasicAuthFilter is giving me so much trouble. I just can't explain it... you might notice my frustration (2am now..)
.Result after the sync method will solve your problem.
like given below.
var filter = Builders<User>.Filter.Eq("email", email);
return _collection.Find(filter).FirstOrDefaultAsync().Result;
However make sure, the Method you're working on isn't marked "async" as an async method should not be blocking. More details here.
AFAIK, MongoDB only provides an asynchronous API, which IMO is a correct design decision.
I can't just keep passing the async tasks up the call hierarchy because at some point the filter expects a sychronous action based on the results.
If this is an ASP.NET WebAPI, you can make it async all the way, since WebAPI supports async filters just fine.
However, if your REST API is ASP.NET MVC, then you're in a hard place. The current version of MVC does not support async filters (or child actions). Note that ASP.NET vNext is merging WebAPI with MVC, and the new merged version does support async filters (and child actions). In the meantime, you'll have to do a hacky solution like replacing MyUserAuthenticationAsync().Wait() with Task.Run(() => MyUserAuthenticationAsync()).Wait(). (Note that MyUserAuthenticationAsync will run on a thread outside the HTTP request context).
Hacks like this should be minimized; they're only necessary in MVC filters and child actions. Regular controller actions should be made async and use await instead of Wait. And if this is WebAPI, then just use await in every scenario; don't use any hacks at all.

Silverlight set cursor to Cursors.Wait

I have a silverlight application. When some action is executed, i want to show a wait cursor.
The problem is that i'm working with threads, and all my actions are executed in a thread.
So i have a threading helper that invokes and awaits all the threads - this works fine.
I need to access the main window element to change its cursor. How can i achieve this?
This:
ThreadingHelper.Invoke(() => App.Current.MainWindow.Content.Cursor = cursorStyle);
Throws me System.NotSupportedException: Out-of-browser specific settings do not affect in-browser applications.
How can i do the same for In-browser?
I have managed to get this working by this code:
ThreadingHelper.Invoke(() => {
var page = (MainPage)Application.Current.RootVisual;
page.Cursor = cursorStyle;
});
But maybe someone will offer more type-safe method?

C# + WinRT + Monogame threading for network (Azure Mobile Service) operations

I have a loop in my application that loops through a set of entities in the following fashion
foreach(var entity in mEntities)
{
entity.Update();
}
Some of these entities maintain a networking component that will call a Azure Mobile Service in order to update their state to the server. An example is below:
public class TestEntity {
public int Index;
public int PropertyValue;
public async void Update()
{
Task.Run(() => {
MyAzureMobileServiceClient.Update(Index, PropertyValue);
});
}
}
The UI rendering is done by Monogame in a more traditional game loop fashion. Whilst I do not know the inner workings of it, I am fairly certain that it does not have an actual separate thread doing the work. In practice, this shows as the UI freezing every time this update is called.
I want to be able to run it "smoothly" in the background. In the old Windows model this could have easily been done by starting a new Thread that would handle it, but I don't understand the threading well enough in WinRT to understand what is wrong with my approach.
Any ideas?
[update] I also tried this:
Task.Factory.StartNew(async () =>
{
while(true) {
await Task.Delay(1000);
MyAzureMobileServiceClient.Update(Index, PropertyValue);
}
});
Every 1 seconds, I get a mini-freeze like before.
[update 2] I tried this with a twist. I replaced the Azure Mobile Service client call with a standard HTTP request and it worked splendidly; no mini-freezes. Granted it wasn't to the backend yet, but at least I have a work around by doing the whole thing manually. Would prefer to not do that, however.
[update 3] This is getting peculiar. I realize I simplified the code in this question in order to get it coherent in the context. However, this appears to have removed the true source of the problem. I tried the following things:
I created a HTTP request and created the request manually, called it inside the Task.Run() and it worked splendidly with no latency.
I called the Azure Mobile Service client Update DIRECTLY and there was no latency.
So this brings me to where the problem lies. I basically have a wrapper class for the Azure Mobile Service. The real path that goes looks roughly like this:
CommunicationClient.UpdateAsync(myObject);
public Task UpdateAsync(MyObjectType obj)
{
var table = mMobileServiceClient.GetTable<MyObjectType>();
return table.UpdateAsync(obj);
}
This causes the lag, but if I do this instead of it, it works with no latency whatsoever:
var client = CommunicationClient.MobileServiceClient;
var table = client.GetTable<MyObjectType>();
table.UpdateAsync(obj);
Soooooo... I should probably refactor the whole question. It's getting tl;dry.
I had a question about how to run things on a backgroundthread and they advised me to use ThreadPool so I would advise you to look at my question and the answer on it maybe you can pick up on some things and get it working on your end.
Create Backgroundthread Monogame

Navigate away after PhoneNumberResult

This is specifically a Caliburn.Micro question I think, as it has to do with how CB handles navigation in windows phone 7.
I have a view that has the option of launching a phone number chooser. Once the result comes back I store it and navigate away, only the navigation wont work. I assume this is because the Handle method is working with the task and not my view. I know I can stick a button down the end of the page to navigate after the handle is finished but I would like this to happen once the result comes back.
This is what I am doing.
public void Handle(TaskCompleted<PhoneNumberResult> message)
{
webtext.Recipient = message.Result.PhoneNumber;
webtext.RecipientDisplayName = message.Result.DisplayName;
CommitWebtextToStorage();
events.Unsubscribe(this);
navigationService.UriFor<ComposeViewModel>();
}
Which wont work. I also can't call a method inside that as that would be the same as what I am doing. I need to let the handle method exit and then call the navigation service.
Actually, the navigation should look like:
navigationService.UriFor<ComposeViewModel>().Navigate();
(note the final Navigate method)
If it was just a typo in the question, I guess the issue could have to do with the timing of application resuming (which occurs when you return back to the application after the chooser task is completed).
In that case, could you please create an issue for this?

A question about making a C# class persistent during a file load

Apologies for the indescriptive title, however it's the best I could think of for the moment.
Basically, I've written a singleton class that loads files into a database. These files are typically large, and take hours to process. What I am looking for is to make a method where I can have this class running, and be able to call methods from within it, even if it's calling class is shut down.
The singleton class is simple. It starts a thread that loads the file into the database, while having methods to report on the current status. In a nutshell it's al little like this:
public sealed class BulkFileLoader {
static BulkFileLoader instance = null;
int currentCount = 0;
BulkFileLoader()
public static BulkFileLoader Instance
{
// Instanciate the instance class if necessary, and return it
}
public void Go() {
// kick of 'ProcessFile' thread
}
public void GetCurrentCount() {
return currentCount;
}
private void ProcessFile() {
while (more rows in the import file) {
// insert the row into the database
currentCount++;
}
}
}
The idea is that you can get an instance of BulkFileLoader to execute, which will process a file to load, while at any time you can get realtime updates on the number of rows its done so far using the GetCurrentCount() method.
This works fine, except the calling class needs to stay open the whole time for the processing to continue. As soon as I stop the calling class, the BulkFileLoader instance is removed, and it stops processing the file. What I am after is a solution where it will continue to run independently, regardless of what happens to the calling class.
I then tried another approach. I created a simple console application that kicks off the BulkFileLoader, and then wrapped it around as a process. This fixes one problem, since now when I kick off the process, the file will continue to load even if I close the class that called the process. However, now the problem I have is that cannot get updates on the current count, since if I try and get the instance of BulkFileLoader (which, as mentioned before is a singleton), it creates a new instance, rather than returning the instance that is currently in the executing process. It would appear that singletons don't extend into the scope of other processes running on the machine.
In the end, I want to be able to kick off the BulkFileLoader, and at any time be able to find out how many rows it's processed. However, that is even if I close the application I used to start it.
Can anyone see a solution to my problem?
You could create a Windows Service which will expose, say, a WCF endpoint which will be its API. Through this API you'll be able to query services' status and add more files for processing.
You should make your "Bulk Uploader" a service, and have your other processes speak to it via IPC.
You need a service because your upload takes hours. And it sounds like you'd like it to run unattended if necessary,, and you'd like it to be detached from the calling thread. That's what services do well.
You need some form of Inter-Process Communication because you'd like to send information between processes.
For communicating with your service see NetNamedPipeBinding
You can then send "Job Start" and "Job Status" commands and queries whenever you feel like to your background service.

Categories

Resources