-
- VBForums
- Visual Basic
- Visual Basic .NET
- VS 2005 Tin can I run a role in the groundwork?
-
May 17th, 2010,04:55 PM #one Thread Starter Lively Fellow member Tin can I run a function in the background? I have a datagrid with a list of items. Each item has an url for a motion-picture show. For each item I have to download the picture from the url, and then evidence it in the filigree. This takes quite a long time, and freezes my application while running. Is information technology possible to do this in the background, while assuasive the user to take other actions? For example, scrolling downwards the list to see the items that take been loaded. Or clicking on an item in the list, which calls some other function. Maybe doing something on a dissimilar form. And doing this while the list continues to load in the background. Is that at all possible? If so, how exercise I do it? (Visual Basic Limited 2005) Last edited by Ron Miel; May 17th, 2010 at 04:58 PM. -
May 17th, 2010,05:04 PM #two Re: Can I run a role in the background? Accept a look at the BackgroundWorker. Here'south a good article on how to ready it up: http://vbnotebookfor.net/2007/09/24/...rker-in-vbnet/ -
May 17th, 2010,09:36 PM #iii Re: Can I run a part in the background? A BackgroundWorker is one way to do this. The problem with that pick is that, unless you apply multiple BackgroundWorkers, it will be done in series. That means that you'll accept to await for one image to download before starting the next. It will probable exist quicker to download multiple images at the same time. For that y'all could use a WebClient and its DownloadDataAsync method. You would create a WebClient, loop through the grid and, for each row, telephone call DownloadDataAsync. DownloadDataAsync allows you to pass a user token that is and then passed back to you when the asynchronous performance completes. You could pass the row index for that image or even the cell itself. I oasis't actually tested anything simply the code would look something like this: vb.net Code: -
Imports System.Net -
Imports System.IO -
Public Class Form1 -
Private Delegate Sub LoadImageIntoGridCellCallback(ByVal cell Equally DataGridViewCell, ByVal img Every bit Paradigm) -
Private WithEvents downloader As New WebClient -
Private Sub DownloadAllImages() -
For Each row As DataGridViewRow In Me.DataGridView1.Rows -
'Get the image URL from the first prison cell. -
Dim url As Cord = CStr(row.Cells(0).Value) -
'Download the image into the second prison cell. -
Me.downloader.DownloadDataAsync(New Uri(url), row.Cells(1)) -
Next -
End Sub -
Private Sub downloader_DownloadDataCompleted(ByVal sender Every bit Object, _ -
ByVal e As DownloadDataCompletedEventArgs) Handles downloader.DownloadDataCompleted -
Dim img As Image -
'Create an Image from the downloaded data. -
Using buffer Every bit New MemoryStream(e.Result) -
buffer.Position = 0 -
img = Paradigm.FromStream(buffer) -
Cease Using -
Me.LoadImageIntoGridCell(DirectCast(e.UserState, DataGridViewCell), img) -
Terminate Sub -
Private Sub LoadImageIntoGridCell(ByVal cell As DataGridViewCell, ByVal img As Image) -
If Me.DataGridView1.InvokeRequired Then -
'Nosotros are on a secondary thread so align a call to the UI thread. -
Me.DataGridView1.Invoke(New LoadImageIntoGridCellCallback(AddressOf LoadImageIntoGridCell), _ -
cell, _ -
img) -
Else -
'Brandish the Prototype in the cell. -
cell.Value = img -
End If -
End Sub -
End Class DownloadDataAsync returns immediately and the download occurs on a thread pool thread, so multiple downloads can occur simultaneously. The DownloadDataCompleted event is raised on that aforementioned thread, which is why you must eventually delegate back to the UI thread to update the filigree. -
May 18th, 2010,06:11 PM #iv Thread Starter Lively Member Re: Can I run a function in the background? Cheers for the replies. I tried Matt's suggestion. I got the sample code working. I so tried to utilise the same method in my own code. I'grand getting an error. vb.net Lawmaking: -
Public WithEvents GetPicturesProcess As Organisation.ComponentModel.BackgroundWorker -
'----------------------------------------------------- -
Individual Sub cmdGetPictures_Click(ByVal sender As System.Object, ByVal e Equally System.EventArgs) Handles cmd_Get.Click -
' start the go pictures process -
GetPicturesProcess = New System.ComponentModel.BackgroundWorker -
GetPicturesProcess.WorkerReportsProgress = True -
GetPicturesProcess.WorkerSupportsCancellation = True -
GetPicturesProcess.RunWorkerAsync() -
End Sub -
'------------------------------------------------------------ -
Public Sub get_the_Pictures(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles GetPicturesProcess.DoWork -
Dim request As WebRequest -
Dim response Every bit WebResponse -
Dim incoming_stream As Stream -
Dim my_picture As Epitome -
Dim loopcount, maxRows As Integer -
Dim picture_url As Cord -
Attempt -
maxRows = Me.dg_ISearchResults.Rows.Count - 1 -
For loopcount = 0 To maxRows -
' get the picture show from galleryurl -
picture_url = Me.dg_ISearchResults.Rows(loopcount).Cells("GalleryUrl").Value -
request = WebRequest.Create(picture_url) -
response = request.GetResponse() -
incoming_stream = response.GetResponseStream -
my_picture = Image.FromStream(incoming_stream, True) -
incoming_stream.Close() -
' put the picture in the filigree -
Me.dg_ISearchResults.Rows(loopcount).Cells("Pic").Value = my_picture -
Next ' loopcount -
Catch ex As Exception -
MsgBox("fault in writing the listing :" + ex.Bulletin) -
Finish Endeavour -
End Sub Information technology downloads the outset picture show successfully, and puts it in the grid, and then throws an exception at line 35. Cross-thread operation not valid: Control '' accessed from a thread other than the thread it was created on. Any idea what I'yard doing wrong? I haven't tried jmcilhinney's suggestion yet. I'll study it now. -
May 18th, 2010,07:22 PM #v Re: Can I run a function in the background? Y'all cannot access controls from any thread other than the one they were created on. You can either practise as I did in my code and employ a consul to marshal a method call to the UI thread, or you can use the machinery built into the BackgroundWorker, which is the whole point of using one. Follow the CodeBank link in my signature and bank check out my post on using the BackgroundWorker component (annotation: component, NOT control) to see how to use the ReportProgress method and ProgressChanged event. -
May 18th, 2010,08:19 PM #vi Re: Tin can I run a function in the background? You can also cheque out the Downloading Queue system I developed...you might exist improve off just implementing something like JMC has suggested/coded for you. -
May 18th, 2010,ten:23 PM #7 Thread Starter Lively Member Re: Can I run a office in the background? JMC, trying your lawmaking I get an error bulletin at line 16 WebClient does not support concurrent I/O operations. -
May 18th, 2010,11:57 PM #8 Re: Can I run a function in the groundwork? Originally Posted by Ron Miel JMC, trying your code I get an error message at line 16 I had a feeling that that might be the case but, equally I said, I didn't really test the code. In that case you volition have to create multiple WebClient objects: one for each download. Become rid of the 'downloader' member variable and the Handles clause on the DownloadDataCompleted consequence handler. Instead, within the loop, do this: vb.cyberspace Code: -
Dim downloader As New WebClient -
AddHandler downloader.DownloadDataCompleted, AddressOf downloader_DownloadDataCompleted -
downloader.DownloadDataAsync(New Uri(url), row.Cells(1)) You should too clean up in the outcome handler: vb.net Lawmaking: -
Dim downloader Every bit WebClient = DirectCast(sender, WebClient) -
RemoveHandler downloader.DownloadDataCompleted, AddressOf downloader_DownloadDataCompleted -
downloader.Dispose() -
May 20th, 2010,ten:36 PM #9 Thread Starter Lively Member Re: Tin I run a function in the background? Fantastic. That works perfectly. Thank you. (I won't mark this resolved just yet, I may need help doing the same thing in other parts of my programme. But this part has been successfully solved) Last edited by Ron Miel; May 20th, 2010 at 10:54 PM. -
Jun 1st, 2010,09:xx AM #10 Thread Starter Lively Member Re: Can I run a function in the background? Okay, some further advice would be appreciated. I don't really understand how it works. Perhaps you could explain information technology flake by bit. I recollect I understand the first ii parts, simply not the third. vb.net Code: -
Individual Sub DownloadAllImages() -
For Each row As DataGridViewRow In Me.dg_ISearchResults.Rows -
'Become the paradigm URL from the first cell. -
Dim url As String = CStr(row.Cells("GalleryUrl").Value) -
If url = "" And then -
row.Cells("Pic").Value = My.Resource.no_image -
Else -
'Download the image into the 2nd cell. -
Dim downloader Every bit New WebClient -
AddHandler downloader.DownloadDataCompleted, AddressOf downloader_DownloadDataCompleted -
downloader.DownloadDataAsync(New Uri(url), row.Cells("Movie")) -
Stop If -
Next -
End Sub I'm non sure if I understand the DownloadDataAsync call. The first argument is the URL that I want to download from. The second argument is where you desire the results to go. Is that correct, or have I misunderstood? vb.internet Lawmaking: -
Private Sub downloader_DownloadDataCompleted(ByVal sender As Object, _ -
ByVal e As DownloadDataCompletedEventArgs) -
Dim img Equally Prototype -
'Create an Paradigm from the downloaded data. -
Using buffer As New MemoryStream(east.Upshot) -
buffer.Position = 0 -
img = Image.FromStream(buffer) -
Cease Using -
Me.LoadImageIntoGridCell(DirectCast(e.UserState, DataGridViewCell), img) -
End Sub Then, e.Result contains the data returned from the URL. And e.UserState is whatever was passed in the the 2d argument for DownloadDataAsync. Is that right, or am I wrong? vb.internet Code: -
Private Sub LoadImageIntoGridCell(ByVal cell As DataGridViewCell, ByVal img Every bit Paradigm) -
If Me.dg_ISearchResults.InvokeRequired And so -
'We are on a secondary thread and then align a call to the UI thread. -
Me.dg_ISearchResults.Invoke(New LoadImageIntoGridCellCallback(AddressOf LoadImageIntoGridCell), _ -
cell, img) -
Else -
'Display the Paradigm in the cell. -
prison cell.Value = img -
Terminate If -
Stop Sub And this I don't follow at all. What is happening here? What does information technology mean to invoke it? Take I understood that it calls itself recursively, doesn't piece of work the beginning fourth dimension, but works the second? I am currently doing something a little unlike to my previous question. I'm at present trying a number of URLS that render text, non pictures, and storing the results in an array. The method IsInvokeRequired only works on controls. What should I do for an array? Also, you've shown me how to extract an image from the returned data, but how to extract text data? Specifically XML, if it makes a divergence. -
Jun 1st, 2010,06:07 PM #11 Re: Can I run a function in the background? You are correct on the first 2 counts. The WebClient supports synchronous and asynchronous operations. Synchronous methods, e.m. DownloadData, will block the current thread until the operation is complete. That's not going to make for a very user-friendly app. Asynchronous methods, eastward.g. DownloadDataAsync, will return immediately while the performance is performed on a background thread. When you call DownloadDataAsync you laissez passer information technology the URL of the data you want to download, as you said, and optionally an object. That object will be returned to you in the DownloadDataCompleted event handler via the e.UserState property, equally you said. Information technology's completely up to the developer what this object is because it is completely application-specific. In this case, we need to know what grid cell to load the data into once we get it, so it makes sense to pass that cell as the user country. In some other awarding it would brand sense to pass something unlike, or mayhap nothing at all. One problem your code has is that yous're not cleaning up in the event handler every bit I said yous should. The trouble there is that each WebClient y'all create is continued to the current object, probably a form, via that event handler. If y'all don't use RemoveHandler so the system cannot make clean up those WebClients, so they will continue to occupy retentivity. With regards to the last code snippet, yous're on the right rail. As I said, DownloadDataAsync downloads the information on a background thread. Every bit such, the DownloadDataCompleted event is raised on that background thread, so your event handler is executed on that same background thread. Now, information technology's basically illegal to access controls from a thread other than the UI thread. As such, each fourth dimension that LoadImageIntoGridCell method is chosen, it checks what thread it'southward existence executed on. If it's on the UI thread then it goes ahead and accesses the UI (in this example, the filigree) directly. If it'southward not on the UI thread and then information technology has to call itself once again, simply non merely with a regular recursive call. In this case it must ask a control to invoke it via a delegate. This allows the phone call to cross the thread boundary to the UI thread and exist executed at that place. For more data, you lot might like to follow the CodeBank link in my signature and check out my posts on Accessing Controls From Worker Threads. -
Jun 2nd, 2010,09:18 PM #12 Thread Starter Lively Member Re: Can I run a function in the groundwork? Thanks. 1 more question. How tin I tell my program to pause until all asynchronous requests are completed? I've tried having a counter, increasing it by one every time I call DownloadDataAsync, and and so decreasing it past i when DownloadDataCompleted operates. Then I have a loop While counter > 0 End While This doesn't work, it merely goes round forever. The DownloadDataCompleted sub only operates if I step beyond the loop. -
Jun 2nd, 2010,09:52 PM #xiii Re: Can I run a function in the groundwork? That'due south not a good pick regardless because what you have there is called a "busy waiting" loop. The thread doesn't progress beyond that point, so it's waiting in a manner of speaking, but it'south actually executing that loop then it keeps the processor decorated doing so. As such, y'all are using up valuable processor time doing nil useful. If yous want to await then yous should actually await and practise nothing in the mean time. You do take a flake of a problem though. If you do really wait on the UI thread until all downloads are complete so your UI will freeze. It also means that you can't delegate back to the UI the load an downloaded image into the grid because the UI thread is waiting for all downloads to consummate. Y'all actually need to give some real consideration to exactly how y'all want the app to behave. Multi-threading has a addiction of making things more circuitous. -
Jun 3rd, 2010,01:05 AM #14 Thread Starter Lively Member Re: Tin I run a function in the background? Well, it's not pictures in the datagrid whatever more, I'm working on something different. Now I'thousand downloading various text records. I save them in an array, then when the array is full I generate HTML from it. I need to make sure that all the records are returned before I generate my HTML. How do I wait and practice null in my program? and how practice I tell that all downloads have finished, so I can terminate waiting? -
Jun tertiary, 2010,01:20 AM #xv Re: Can I run a function in the background? I've never used one myself, then I can't become into details, only I think yous desire to await at the WaitHandle class and its WaitAll method. The documentation has a code instance then that should get you started. -
Jun third, 2010,01:30 AM #16 Re: Can I run a function in the background? Originally Posted past Ron Miel I have a datagrid with a list of items. Each item has an url for a picture. For each item I take to download the flick from the url, and and so prove it in the grid. This takes quite a long time, and freezes my application while running. Is it possible to do this in the groundwork, while allowing the user to take other actions? For example, scrolling down the list to meet the items that have been loaded. Or clicking on an item in the list, which calls another function. Maybe doing something on a different form. And doing this while the list continues to load in the groundwork. Is that at all possible? If so, how do I do it? (Visual Basic Express 2005) I'grand going to suggest something dissimilar but still your particular case can be solved this fashion - generate a HTML lawmaking for your pics and feed it to a web-browser control. If you have a 3x2 tabular array with pics on the 2nd cavalcade yous can generate it like this: Simplified version: HTML Lawmaking: <html> <head> </head> <torso> <tabular array> <tr> <td> </td> <td> <img src="your link here" /> </td> <td> </td> </tr> <tr> <td> </td> <td> <img src="your link here" /> </td> <td> </td> </tr> </table> </body> </html> It volition load pretty fast and you can always admission each element of your tabular array. -
- VBForums
- Visual Basic
- Visual Basic .NET
- VS 2005 Can I run a function in the groundwork?
Posting Permissions - Y'all may not post new threads
- You lot may not post replies
- You may not post attachments
- You may non edit your posts
- BB lawmaking is On
- Smilies are On
- [IMG] code is On
- [VIDEO] code is On
- HTML code is Off
Forum Rules | Click Here to Aggrandize Forum to Full Width |
0 Response to "Do Code In Background Vb.net"
Post a Comment