Question

Threads a + b, (both are trying to delete files). a gets called first, then b while a is still running. b deletes the file successfully but a doesn't.

If I run a on its own, a's file deletes fine.

When I step through the code I can see that a's MultiAttemptFilename gets overwritten with b's.

I don't understand.

I have an ajax call pointing to a generic handler which passes the filename along with it. In my handler I have the following code:

    Dim Dc As New Document
    Dim MyThread As New Thread(AddressOf Dc.DeleteFileMulitAttempt)
    Dc.MulitAttemptFilename = Filename
    MyThread.Start()

From my 'Document' class I'm calling the following:

    #Region "Delete"

  Public MulitAttemptFilename As String = ""
  Public Sub DeleteFileMulitAttempt()
      Dim TimeBetweenAttempts As Integer = 2000
      Dim NumberOfAttempts As Integer = 60
      Dim AttemptNumber As Integer = 0
      Dim Success As Boolean = False
      While (AttemptNumber < NumberOfAttempts)
          Try
              Success = (DeleteFile(MulitAttemptFilename) = "Ok")
          Catch ex As Exception
              Success = False
          End Try
          If (Success) Then Exit While
          Thread.Sleep(TimeBetweenAttempts)
          AttemptNumber += 1
      End While
      End If
  End Sub

...

This is to handle cancelled/failed uploads as they don't always delete right away (server locks etc), hence the loop.

Am I missing something fundamental here?

Was it helpful?

Solution

It seems like you might be missing the fundamental concept of multi-threaded concurrency. There are books dedicated to this, and often sections of .NET books will address this issue. Here's just one article by Microsoft on the topic.

One short answer is you need to use VB's "lock" keyword. You create an object and you do roughly something like

lock(yourLockObject)
{
   //any code that might access a shared resource like the variable 
   //MulitAttempFilename [sic] would go here. 
}

I don't speak VB but it looks like you're making the one thing that really needs to be protected a global variable. Global data is pretty much a bad idea in any form and when it comes to multi-threading it's a really, really bad idea. You'll have to rewrite your code to protect access to the name of the file being deleted. While you're reading up on multi-threading you might also want to learn about thread pools.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top