.net - Using Task For Async Operation But UI Is Still Unresponsive
Jun 14, 2012
I have a WPF application in which i have to do a long running task (basically reading from network). Just to give you a snapshot I am doing the following thing on button click
Dim t As Task(Of String) = Task.Factory.StartNew(Of String)(Function()
'Thread.sleep is simulating long running task that will make UI unresponsive
Thread.Sleep(10000)
[Code].....
I cannot use Event based async methodology because the reading API actually exist in a dll which i refer in my program, that contains a function Public function ReadFromNetwork() as String. This API is making an async call to network to read a long string and return to UI. So, in short i m doing TextBlock1.Text = ExternalDll.ReadFromNetwork().
but the problem is that even if i use Task asynchrony, the UI is still unresponsive.
I've created an httplistener and I'm using the async method it has.Starts like this on a BUTTON click in my test app
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click Dim prefixes() As String = {"http://*:8080/HttpListener/"} StartRequests(prefixes) End Sub
[code]....
This forces the callback to fire - for some reason that I don't quite understand and it gets this error...
Quote:
The I/O operation has been aborted because of either a thread exit or an application request at this line
Private Sub GetContextCallBack(ByVal result As IAsyncResult) 'Dim listener As HttpListener = CType(result.AsyncState, HttpListener) Dim context As HttpListenerContext = m_listener.EndGetContext(result)
I'm trying to write a 'developer friendly' wrapper for the Windows API EnumWindows - the problem is that the API uses a callback function that gets invoked on another thread, where as I want my wrapper function to simplify this and make it more useful by working like any other normal synchronous function and just returning a value.
Now if the API just called the callback once that would be fine, as I would just call the API and make the wrapper function wait until it got a signal from the callback function telling it to continue... but the API calls the callback function over 100 times (once for every window handle that exists). The biggest problem is that there is nothing that indicates that any particular call to this callback function is the last one, so my wrapper function has no idea when it is safe to continue and return the list of window handles to the caller.
The only solution I could think of is to do this:
1. The wrapper function calls the API and starts a timer that waits 2 seconds before it raises the Elapsed event. The wrapper function then pauses until it receives a signal (ManualResetEvent)
2. Each time the callback function is raised by the API on a different thread, it stops the timer (so this is before the 2 seconds have elapsed), adds the current window handle that was passed in by the API to the list of handles, then starts the timer again.
3. If the timer reaches its 2 second interval then it is assumed that we are at the end of the windows because otherwise the callback would have stopped the timer. So the timer's Elapsed event handler is what signals the original thread (that the wrapper function is executing on) to continue as we now have a complete list of windows to return.
This works fine and does exactly what I want... but I dont like it.
I dont like forcing the caller to wait an extra 2 seconds after the API has done its last callback but more importantly I dont like assuming that the API will never take longer than 2 seconds between callbacks. In reality on my PC it is never anywhere near that long between callbacks, it is something like 200 miliseconds, but I have no idea how long it would be on a slower PC and I want this to be completely reliable.
I'm using task.factory to make threads and start having the "Cross-thread operation not valid" error when trying to update the main form.I search for this error and tried some examples of code, using delegate for example, but all result in some deadlock.
I've recently just started looking into TCP sockets for Server-Client communications in VB.Net(VS2010); which I have working fine whilst on a single form. However, when I try to load another form it calls the form_load part and runs that part, but then appears as if it's in an endless loop on the original form because the mouse turns to time out whilst on the new form. Client side Login form(works fine and is responsive)
Public Class Login Private client As System.Net.Sockets.TcpClient Private Const BYTES_TO_READ As Integer = 255[code]....
Tried breakpointing to find out where the loop appears to be and I think its in the doRead sub.
I'm making an Install Manager and when you hit the install button a dialog is suppoed to come up saying that your installing and theres no way to track your installation and some other stuff but it only pops up after all the software is downloaded and while its installing. The finish button is supposed to show up when everything is completed that they checked off. Instead, the dialog pops up after it finishes downloading and while it's installing. It also shows the finish button before it's finished installing. Heres the necessary code
Dialog1.vb Imports System.Windows.Forms Public Class Package_Installation
I have an application which runs quite good, only once every X minutes it totally freezes, and even when running debug mode from within the VS2005 IDE, Visual studio becomes unresponsive. After pressing the pause-button to see where the app might be stuck, a messagebox saying "Unable to break execution" might pop-up after a minute or two. My app uses some timers, threads, and threadpool calls. So I'm afraid I got a deadlock somewhere, although I can not find it. Is there any way to find out where my app might hang?
Note: I synclocked every routine with a dedicated object, and for queues or arraylists, I even used the synchronized methods to modify them. I don't use recursive routines, so they cannot deadlock themselves. The strange thing (to me) is that all of my app hangs, none of the threads seems to be running, nor background, nor the GUI and even the VS environment.
i have a vb.net application that plots 16 plots immediately, the plots data are realtime. the 16 plots must draw the points at the time they receive them (must be no delay), to do that
1- i made a timer with ticks at 50 ms.
2- at each timer tick call the plotting function 16 times (with a graph name as parameter)like that: [code] it made a big delay, when i used threading the application became unresponsive.
is it guaranted that a task A started before TaskB will be completed before task B assuming the task do the same level of operatons?or in other words is there a chance that a task B will finish before tast A in the assumption that the task calls the same procedure?
I have an application (written in VB.net 2008) which reads a text file. Parses the record and uses the second field (a UK postcode) to match an Access database (SQL - Select * from Table1 ......), then writes a text file back out with the original input postcode plus several fields taken from the access database.
I have 3 counts happening during the process, records read, postcodes matched and postcodes not matched. I move these values to labels on the form, then every 50 records read, I refresh the form (me.refresh) to update the labels (showing the end user where the process is upto).When running, if I drag the window around the screen, or minimize then maximize, or click off the window to another window, the application seems to freeze and the counter labels do not refresh.
I'm currently trying to write a football simulator but am having issues with the computer becoming unresponsive. There are long lines of code (several thousand lines) that are executed over and over as one run of the code is equivalent to one second of game time. While the game is setup to be like Football Manager where you watch the game live, there will also be cases where the entire game is simulated without you watching. When doing a full sim of a game, I just have a loop which executes the code block 7200 times (games go for two hour roughly).
At the moment this takes about a minute but even when I get it down to the desired 5-10 seconds or so, I dislike the fact that the computer becomes completely unresponsive during this time. In a round there are 9 games and you'll be simulating without watching 8 of them. You're looking at 1-2 minutes of simulation time or possibly more. I can't have a loading screen that long! How can I program the game so it runs these simulations yet the game still remains responsive? It'd be fine if the user could muck around in the menus and stuff while the simulation runs.
The coding that I have a problem with might make people think that I am creating some malware or something stupid. So the project I am doing is associated with iTunes. iTunes allows people to have one library. There is another way, but it is very confusing to some people, and very unreliable. So my project is that I will allow people to have multiple iTunes libraries on one computer. So the problem is this. In order to have an option to choose your library, I gotta make sure that iTunes is not running. So this is the script:
Code: Private Sub CheckAndCloseiTunes() retry: 'Custom class that includes the function to safely close iTunes
[CODE]...
So when I use the Threading.Thread.Sleep(2000) code, the form becomes unresponsive.
The coding that I have a problem with might make people think that I am creating some malware. So the project I am doing is associated with iTunes. iTunes allows people to have one library. There is another way, but it is very confusing to some people, and very unreliable. So my project is that I will allow people to have multiple iTunes libraries on one computer. So the problem is this. In order to have an option to choose your library, I gotta make sure that iTunes is not running.
So this is the script:
Private Sub CheckAndCloseiTunes() retry: 'Custom class that includes the function to safely close iTunes Dim Processes As Process() = Process.GetProcessesByName("iTunes")
[CODE]...
So when I use the Threading.Thread.Sleep(2000) code, the form becomes unresponsive.
I have two methods on the page. One AddMessageToInboxOutbox(params[]) and other one SendNewMessageMail(params[]).
Once user sends an message to other other first message is added to DB and then sent to recipient's email. Sometimes SMTP is heavy loaded and it takes up to 5 seconds to get answer from it. I want to enclose SendNewMessageMail(params[]) with async call using other thread or something. I have never done that.
In my scenario the Button_Click is a command delegate in the VM, and the Thread.Sleep is some long-running process (about 2-10 seconds). I want, that when the user calls the command, it should immediately update the UI disabling the button so the user cannot execute it while it's running, then execute that operation, then, when operation completed, unblock the button.
I have a bunch of operations that need to be executed simultaneously. For this I'm using the thread pool to execute the tasks. I'd like to know if it's possible to consume some sort of Async Callback (similar to BackgroundWorker.DoWorkComplete) when each thread is finished. The reasoning behind this is that I have a windows service running that uses IPC to update a GUI and I need to know the time at which each specific thread finishes I've used background workers to do a set of tasks and they work perfectly, however, they take longer than I would like. I've timed the execution on my BGW method for a designated number of said tasks and it took 27 seconds, and the same set of tasks takes 4 seconds using the threadpool method. I've also tried using managed threads, to the same effect as the background workers.
Async Sub like this: Dim f As Func(Of Task) = Async Sub() End Sub Produces compiler error: error BC36670: Nested sub does not have a signature that is compatible with delegate 'System.Func(Of System.Threading.Tasks.Task)'.Equivalent C# code compiles fine:
Func<Task> f = async () => { };Rewriting Async Sub into Async Function make code works.
Why does Async Sub() is not convertible to delegate types with return value of type Task?
I think this is a simple question for you, but I don't understand other cases of webRequests, so I asked here: How can I make this webRequest asynchronous? Dim sBuffer As String Dim oRequest As WebRequest = WebRequest.Create(url) oRequest.Method = "GET" Dim oResponse As WebResponse = oRequest.GetResponse() Dim oStream As New StreamReader(oResponse.GetResponseStream()) [Code] .....
I want to create an asynchronous function that initiates a layout update and then Awaits for the layout update to complete. Something like:
Private Async Function UpdateLayoutRoot() As Task LayoutRoot.UpdateLayout() Await LayoutRoot.LayoutUpdated <--- (NOT valid but shows desired outcome) End Function
How can this be done? More generally, how can you use Await to wait for existing events?
I have some code that iterates a few 100 urls and requests the data from the web.It looks something like this
for each url in urls Dim hwr = CType(WebRequest.Create(url), HttpWebRequest) Dim rq = New ReqArgs
[code]....
How come the BeginGetresponse line takes about 2-3 seconds to complete before going to dim a=1?. Actually I debugged and I see that the FinishWebRequest procedure runs completely before the Dim a=1 is reached.So is this async?I'm not earning any time by using the async. am I? Or is there a different way to do this?The point is that the main sub should fire off 300 requests and return control to the UI, then the FinishWebRequest should process them slowly on its own thread and own time , as the requests come in.How do I do that?Btw, the main sub is running in a BackgroundWorker, but I checked with out the BackgroundWorker and the problem is the same?
I've run into a bit of a problem using Async ping. Basically, I want to ping computers in the list before I run the next bit of my program. The computers who I can ping are added to a list and that is used in a background worker. Trouble is can't seem to work out how to wait until after pinging ALL computers in the list, either successful or timed-out. Is there something a long the lines of 'If Async Ping is running'?
Private Sub pingCompleted(ByVal sender As Object, ByVal e As System.Net.NetworkInformation.PingCompletedEventArgs) If e.Reply.Status = Net.NetworkInformation.IPStatus.Success Then complist.Add(e.UserState) Else 'do nothing End If End Sub
I need the next bit to wait because if 'complist' is changed while it's being used I get collection errors.
I am working on moving a project from VB6 to VB 2008 Express. [Code] When I connect to mysql db in VB6, I connect using adAsynConnect. This way, I have a "Loading..." animation display while a connection is attempted. Is there a way to do this in 2008 Express? Or something similar I could read up on?
Basically in my main application i am instantiating the client class from this dll, as well as the server one. On the client form i got a "send data" (SendFISA sub) and a "connect" button. After connecting the client and clicking on the "send data" i am sending to the server a string formed of some information created when instantiating the client class from the dll (i can't make that type of data public, but i'm just using a constructor to assign values to a class object, nothing special).
Now, when the server receives the data sent by "send data" button click it responds with "PKG_SENT" corresponding to the "FISASENT" string terminator(in the module) of the string that was sent. The "WRONG_MSG" constant is for when the string terminator is different from the 2 from above.
On the local disk, if the server cannot be reached, the client saves an xml file with this data. In the dll i made a timer that ticks every 5 seconds and checks to see if there is any xml file on the disk and sends it to the server if the connection is ok (trimiteXML sub). The server would respond with "XML_SENT" corresponding to the string terminator "XMLSENT"(in the module) appended to the read string from the xml file. After the file is sent it is deleted from the local dir.
The problem occurs when i click "send data" AND there are XML files to be sent from the disk. I believe they are interpreted by the server somehow at the same time because the message is neither "PKG_SENT" nor "XML_SENT", but it becomes a combination of the "WRONG_MSG_TYPE" and "XML_SENT", "XML_SENTG_TYPE". I have no idea why this is happening and i basically want the socket to wait with sending the files from the disks until the "send data" finishes.
I have a console app that is supposed to async call a web service...i don't get any errors but the completed handler doesn't seem to complete correctly. I have a subroutine with a loop that is supposed to fire off say 6 seperate calls to another routine that calls the service. The completed event handler routine puts data into the database..If i put a thread.sleep under the call to the routine calling the web service. The completed event handler fires but only one record is put in the database instead of the hundreds expected and only that one webservice call appears to fire.I should mention that this works as expected when calling the sync method of the web service within a console app and the asyc calls work as expected from a windows forms app. I just need it to work async within a console app..
I'm trying to setup an asynchronous client and I can send/receive one command and response, but when I try to send the second command, the command is sent (I verified by code inspection), but I am getting no response.
Heres the code, a majority of it is from the Microsoft example.
Option Explicit On Imports System Imports System.Net
My app is basically talking to a device via RS232. I need to 'listen' to the data received and do certain things based on it, update labels, etc. When I started, I only had a couple cross-thread calls and I used JMC's example to get by that. Now my app is bigger and I am calling the ThreadProcSafe all the time. I am hoping there is an easier way so I don't have to create sub routines for every control. Here's the relevant parts of my code.
Private Sub StepperSerialPort_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles StepperSerialPort.DataReceived Dim ReceiveBuffer As String
Alright Simple question I got my main thread running Form Load and I make a socket then called BeginAcceptthen I pass AR to a Function that handles the Accept and creates a whole another sockets out of it and then loops for recv then when it gets everything closes then exits the functionbut how do I make the Socket from Form_Load run BeginAccept again to wait for another connection.. Do I call that command and Point it to the same Block thats Currently running, The block that Handles the AR Param??