We have a Silverlight 4 application utilizing an IDuplexSessionChannel to send data to/from the application to a WCF service.
I've noticed that during very high UI thread usage (such as application startup when the UI is building itself) calls to our WCF service via IDuplexSessionChannel.BeginSend are not sent until the UI has completed rendering.
The calls to BeginSend are being done within a BackgroundWorker.
Does the actual execution of BeginSend occur on the main thread? I couldn't find anything "official" that documents this.
It would seem so since even if I have the main thread Sleep or WaitOne the messages still do not go through (note this was just a test).
What would be the best way to get those calls to go out immediately?
Thanks
Related
Suppose my WCF Service Application is "single-threaded" and I process some stuff on a background thread, but then need to service the processed data on the main IIS thread. (conversely, and seemingly more easily, I could lob all incoming methods to be re-called on the background thread, but this is not what I'm asking).
How can I, from the background thread, "notify" the main thread that my WCF methods are being invoked upon, to "wake up" and go process a method I specify?
I'm not super-familiar with the inner workings of WCF & IIS. I'm taking a guess that my service's methods are being called from completion ports and I should take as little time as possible in them, to prevent the IO servicing stuff from choking. I'm starting to think that if I want everything synchronized on one thread (calls to my methods, and my video-processing operations I need to perform), then I should make a command q and put all incoming method calls onto the command Q.
Surely this is an extremely common scenario. How do most people do this?
From my understanding, you are trying to run something in background, and process something else further based on the result from background job.
Maybe you can try the Task, which you can specify the callback (Task.ContinueWith) when the task is finished.
The GUI of my program freezes while the program is doing its work. I created a mass import which can send X-thousand datarows via a called webservice into a database. The code is already very big and I cannot rewrite it for multithreading purpose.
I don't know how to do it. Any suggestions? If needed I will show some code, but at the moment I don't know what to show.
Firstly, you should rewrite it to use avoid synchronously doing this on the UI thread. If you do a lot of work on the UI thread, it simply will freeze the UI thread. There are a few options here:
If your web service proxy supports asynchronous calls, and if you're using VB 11, you can use Async / Await to call the web service asynchronously from the UI thread in an asynchronous method, and control will return back to the UI thread at the same point in the asynchronous method when the call has completed. It takes a little while to get your head round asynchrony, but this is probably the best option if it's possible.
You can use the Task Parallel Library to make calls on a different thread, but then you'll need to think carefully about how that thread is going to interact with your UI thread.
You can use BackgroundWorker to run some code on another thread, but report progress and completion back on the UI thread
You could potentially call Application.DoEvents between each web service call, to let the UI handle events. This is dangerous - it can lead to re-entrant code, so locks won't behave as you expect them to, and similar hard-to-diagnose errors. This should be your last option, if all else fails.
I have some functions in a web application that do a lot of calculations and as a result have high CPU usage which affects the rest of the application when other users are accessing it.
I have tried backgroundworker to no avail , the only thing that seems to work in using another thread and setting the priority to low, can the UI be updated from a worker thread? specifically I am trying to bind a grid to a dataset processed in the worker thread
If you call Application.DoEvents() periodically to process the windows message queue, this will allow the UI to be updated and respond to user input.
You need to understand that many people consider DoEvents to be evil. As the UI will respond to events such as click, you should beware of any issues this can cause such as allowing many of your heavy CPU BackgroundWorker threads to be spawned. However, used correctly DoEvents provides a valid strategy for keeping your application responsive during processing.
I have a WCF service method that I want to perform some action asynchronously (so that there's little extra delay in returning to the caller). Is it safe to spawn a System.ComponentModel.BackgroundWorker within the method? I'd actually be using it to call one of the other service methods, so if there were a way to call one of them asynchronously, that would work to.
Is a BackgroundWorker the way to go, or is there a better way or a problem with doing that in a WCF service?
BackgroundWorker is really more for use within a UI. On the server you should look into using a ThreadPool instead.
when-to-use-thread-pool-in-c has a good write-up on when to use thread pools. Essentially, when handling requests on a server it is generally better to use a thread pool for many reasons. For example, over time you will not incur the extra overhead of creating new threads, and the pool places a limit on the total number of active threads at any given time, which helps conserve system resources while under load.
Generally BackgroundWorker is discussed when a background task needs to be performed by a GUI application. For example, the MSDN page for System.ComponentModel.BackgroundWorker specifically refers to a UI use case:
The BackgroundWorker class allows you to run an operation on a separate, dedicated thread. Time-consuming operations like downloads and database transactions can cause your user interface (UI) to seem as though it has stopped responding while they are running. When you want a responsive UI and you are faced with long delays associated with such operations, the BackgroundWorker class provides a convenient solution.
That is not to say that it could not be used server-side, but the intent of the class is for use within a UI.
I have a web service, implemented with WCF and hosted in IIS7, with a submit-poll communication pattern. An initial request is made, which returns quickly and kicks off a background process. The client polls for the status of the background process. This interface is set and can't be changed (it's a simulation of an external service we depend on).
I implemented the background processing by adding another service contract to the existing service with a one-way message contract that starts the long-running process. The "background" service keeps a database updated with the status in order to communicate with the main service. This avoids creating any new web services or items to deploy.
The problem is that the background process is very CPU intensive, and it seems to be starving the other service calls out. It will take up an entire processor, and while a single instance of the background process is running, status polling calls to the main service can take over a minute. I don't care how long the background process takes.
Is there any way to throttle the resource usage of the background method? Or an obvious way to do long running async processes in WCF without changing my submit/poll service contract? Would separating them into different web services help if the two services were still running on the same server?
The first thing I would try would be to lower the priority.
If you're actually spinning off a separate process for the background work, then you can do it like this:
Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.BelowNormal;
If it's really just a background thread, use this instead (from within the thread):
Thread.CurrentThread.Priority = ThreadPriority.BelowNormal;
(Actually, it's better to start the thread suspended and change the priority at the caller before running it, but it's generally OK to lower your own priority.)
At the very least it should help determine whether or not it's really a CPU issue. If you still have problems after lowering the priority then it might be something else that's getting starved, like file or network I/O.