Thread.Join (int) does not kill thread after specified timeout in C #

In my Windows Form application, I am trying to test the user's ability to access a shared folder on a remote computer. The way I do it (and I'm sure there are better ways ... but I don't know about them) is to check if a specific directory exists on the remote machine (I do this due to firewall / other security restrictions I collided in his organization). If the user has permission to access the shared folder, it comes back in no time, but if they don't, it hangs forever. To solve this problem, I dropped the check into another thread and waited only 1000 milliseconds before determining that this resource could not be harmed by the user. However, when I do this, it still hangs like it never started on the same thread.

What is causing it to freeze and how to fix it? I would have thought that the fact that it is on a separate thread would let me just let the thread finish on its own background.

Here is my code:

bool canHitPath = false;
Thread thread = new Thread(new ThreadStart(() =>
{
    canHitPath = Directory.Exists(compInfo.Path);
}));
thread.Start();
thread.Join(1000);

if (canHitPath == false)
{
    throw new Exception("Cannot hit folder: " + compInfo.Path);
}

      

Edit: I feel like I should add that line for IS HIT exceptions . I debugged this and tested it ... however when an exception is thrown then when my program hangs. (I can also add that the exception is caught in the calling method and I never get a catch statement in the debugger.)

Edit: So, I found the answer to this question ... but I can not pick your answer as a reply within 24 hours ... so until then ... you will click on the following link: qaru.site/questions / 1898719 / ... Sorry.

+3


source to share


5 answers


I found the real problem:

The compInfo.Path property checks the existence of a directory on the remote file system to determine if the remote computer is 64-bit or not. Depending on the results, it returns a different value. I tried to comment on the check and it succeeded. This explains why I couldn't get past the throw of the exception, I call compInfo.Path on the exception message.

However, I think we have learned a lot from the "real problem":



  • The code I posted in the question (as is) works great.
  • thread.Join (int) will exit after the specified time interval, regardless of whether the thread can still execute code.
  • A linked thread MAY start an I / O operation (thus linking a file / directory) and the desired result will occur when the .Join (int) stream is executed.
  • Using the "step in" button in the debugger will show a lot of things ... even about your own "hard" code. :)

Thank you all for your help, patience and thoughtful input / understanding.

+2


source


I guess this will happen because when you call:

canHitInstallPath = Directory.Exists(compInfo.InstallPath);

      

The method Exists

contains the thread of execution of the protector (it is an uninterrupted call). If it hangs for 30 seconds, their thread will wait 30 seconds until it can check if it has passed Thread.Join(1000)

.

Note that the Thread.Join () method only blocks the calling thread (usually the application's main thread of execution) until your thread object finishes. You still have other threads running in the background, waiting for your particular thread to finish.

From:

Thread.Join Method (System.Threading)

One more thing to consider: checking only if the folder exists says nothing if the user can read or write files to the folder. Your best option is to try to write or read the file in the folder. This way you can make sure the user has permissions on this folder.



EDIT

In your cases, streams only make sense if you can do other things while waiting for the stream to complete. If you can't, their threads won't help you at all.

EDIT2

Link to support my answer: File descriptors and multithreaded programs

EDIT3

It is best to create a killer flow. This thread will kill the thread DirectoryExists

if it hangs for more than X seconds.

+2


source


It is clearly stated in your comments that the exception was actually thrown and caught. Thus, the code execution continued, at least outside of this code, and we cannot tell from this snippet what it does.

You made one mistake, you forgot to set the IsBackground property to true. Without it, the program cannot terminate. This is one of the ways in which you can enter into "blocking!" If this assumption is inaccurate, we will need to see how the call stack of the main thread has an idea of ​​what it is doing. Best captured by enabling unmanaged debugging support and enabling Microsoft Symbol Server so that we can see the entire call stack, not just the managed parts.

A completely different approach is to use the Ping class to test the server.

+2


source


Maybe take a look at the parallel task library . TPL is designed for maximum performance and can handle what could be a problem. Although this can also be a complete overkill for this situation.

0


source


Thread.Join

is a blocking call that will hold the thread that was called from until the thread that was called on exits .

Basically you create a new thread to do background work and then tell the main thread to wait until it finishes. In fact, all of this happens synchronously.

0


source







All Articles