Reference: Implement C# Generic Timeout
I'm currently working on a project that pulls metrics from AWS and my program is just stalling on a few particular calls to ListObjects. I told my supervisor that I was considering using thread abort for this purpose and now he is asking me to write a generic timeout function rather than one specific to this case. This doesn't seem safe. Now I don't completely understand the snippet I'm using from the referenced question, so I'm a little in the dark here.
Call stack on stuck code:
mscorlib.dll!System.Threading.Thread.Sleep(int millisecondsTimeout) + 0x5 bytes AWSSDK.dll!Amazon.S3.AmazonS3Client.pauseOnRetry(int retries, int maxRetries, System.Net.HttpStatusCode status, string requestAddr, System.Net.WebHeaderCollection headers, System.Exception cause) + 0x5b bytes
AWSSDK.dll!Amazon.S3.AmazonS3Client.handleRetry(Amazon.S3.Model.S3Request userRequest, System.Net.HttpWebRequest request, System.Net.WebHeaderCollection respHdrs, long orignalStreamPosition, int retries, System.Net.HttpStatusCode statusCode, System.Exception cause) + 0x17e bytes AWSSDK.dll!Amazon.S3.AmazonS3Client.getResponseCallback(System.IAsyncResult result) + 0x57a bytes
AWSSDK.dll!Amazon.S3.AmazonS3Client.invoke(Amazon.S3.AmazonS3Client.S3AsyncResult s3AsyncResult, bool isRedirect) + 0xcde bytes
AWSSDK.dll!Amazon.S3.AmazonS3Client.getResponseCallback(System.IAsyncResult result) + 0x636 bytes
AWSSDK.dll!Amazon.S3.AmazonS3Client.invoke(Amazon.S3.AmazonS3Client.S3AsyncResult s3AsyncResult, bool isRedirect) + 0xcde bytes
AWSSDK.dll!Amazon.S3.AmazonS3Client.getResponseCallback(System.IAsyncResult result) + 0x636 bytes
AWSSDK.dll!Amazon.S3.AmazonS3Client.invoke(Amazon.S3.AmazonS3Client.S3AsyncResult s3AsyncResult, bool isRedirect) + 0xcde bytes
AWSSDK.dll!Amazon.S3.AmazonS3Client.getResponseCallback(System.IAsyncResult result) + 0x636 bytes
AWSSDK.dll!Amazon.S3.AmazonS3Client.invoke(Amazon.S3.AmazonS3Client.S3AsyncResult s3AsyncResult, bool isRedirect) + 0xcde bytes
AWSSDK.dll!Amazon.S3.AmazonS3Client.invoke(Amazon.S3.AmazonS3Client.S3AsyncResult s3AsyncResult) + 0x53 bytes
AWSSDK.dll!Amazon.S3.AmazonS3Client.invokeListObjects(Amazon.S3.Model.ListObjectsRequest request, System.AsyncCallback callback, object state, bool synchronized) + 0x102 bytes AWSSDK.dll!Amazon.S3.AmazonS3Client.ListObjects(Amazon.S3.Model.ListObjectsRequest request) + 0x31 bytes
First, is the purpose that I want to use this for (Amazon's ListObjects stalling) safe for thread abort?
Second, is there a safe way to do this in a generic function without asynchronous thread aborting?
Here is what I have:
Implementation:
public static class Timeout<TResult>
{
private static int _timeout = 5000;
//WARNING - This method uses asynchronous thread aborting and can result
//in roughhousing and !@#$ hitting the fan
public static TResult Run(Func<TResult> function)
{
if (function == null) throw new ArgumentNullException("function to timeout is null");
var sync = new object();
var isCompleted = false;
WaitCallback watcher = obj =>
{
var watchedThread = obj as Thread;
lock (sync)
{
if (!isCompleted)
{
Monitor.Wait(sync, _timeout);
}
}
if (!isCompleted)
{
watchedThread.Abort();
}
};
try
{
ThreadPool.QueueUserWorkItem(watcher, Thread.CurrentThread);
return function();
}
catch (ThreadAbortException)
{
Thread.ResetAbort();
return default(TResult);
}
finally
{
lock (sync)
{
isCompleted = true;
Monitor.Pulse(sync);
}
}
}
}
The call:
response = Timeout<ListObjectsResponse>.Run(() => s3Client.ListObjects(request));
Well I guess I don't need to use generics, I found the cause of the root problem with amazon AWS. Apparently, if the name of the bucket has a period in it and the region isnt US(east), a specific endpoint needs to be configured for the client.