参考: 实现 C# 通用超时
我目前正在从事一个从 AWS 提取指标的项目,而我的程序只是在对 ListObjects 的一些特定调用上停滞不前。我告诉我的主管,我正在考虑为此目的使用线程中止,现在他要求我编写一个通用的超时函数,而不是一个特定于这种情况的超时函数。这似乎并不安全。现在我不完全理解我在引用问题中使用的片段,所以我在这里有点摸不着头脑。
在卡住的代码上调用堆栈:
mscorlib.dll!System.Threading.Thread.Sleep(int millisecondsTimeout) + 0x5 字节 AWSSDK.dll!Amazon.S3.AmazonS3Client.pauseOnRetry(int retries, int maxRetries, System.Net.HttpStatusCode status, string requestAddr, System.Net. WebHeaderCollection 标头,System.Exception 原因)+ 0x5b 字节
AWSSDK.dll!Amazon.S3.AmazonS3Client.handleRetry(Amazon.S3.Model.S3Request userRequest,System.Net.HttpWebRequest 请求,System.Net.WebHeaderCollection respHdrs,long orignalStreamPosition,int重试,System.Net.HttpStatusCode statusCode,System.Exception 原因)+ 0x17e 字节 AWSSDK.dll!Amazon.S3.AmazonS3Client.getResponseCallback(System.IAsyncResult 结果)+ 0x57a 字节
AWSSDK.dll!Amazon.S3.AmazonS3Client.invoke(Amazon .S3.AmazonS3Client.S3AsyncResult s3AsyncResult, bool isRedirect) + 0xcde 字节
AWSSDK.dll!Amazon.S3.AmazonS3Client.getResponseCallback(System.IAsyncResult 结果) + 0x636 字节
AWSSDK.dll!Amazon.S3.AmazonS3Client.invoke(Amazon.S3.AmazonS3Client.S3AsyncResult s3AsyncResult, bool isRedirect) + 0xcde 字节
AWSSDK.dll !Amazon.S3.AmazonS3Client.getResponseCallback(System.IAsyncResult 结果) + 0x636 字节
AWSSDK.dll!Amazon.S3.AmazonS3Client.invoke(Amazon.S3.AmazonS3Client.S3AsyncResult s3AsyncResult, bool isRedirect) + 0xcde 字节
AWSSDK.dll!Amazon。 S3.AmazonS3Client.getResponseCallback(System.IAsyncResult 结果) + 0x636 字节
AWSSDK.dll!Amazon.S3.AmazonS3Client.invoke(Amazon.S3.AmazonS3Client.S3AsyncResult s3AsyncResult, bool isRedirect) + 0xcde 字节
AWSSDK.dll!Amazon.S3.AmazonS3Client.invoke(Amazon.S3.AmazonS3Client.S3AsyncResult s3AsyncResult) + 0x53 字节
AWSSDK.dll!Amazon.S3.AmazonS3Client.invokeListObjects(Amazon.S3.Model.ListObjectsRequest 请求,System.AsyncCallback 回调,对象状态,布尔同步)+ 0x102 字节 AWSSDK.dll!Amazon.S3.AmazonS3Client.ListObjects(Amazon.S3.Model.ListObjectsRequest 请求)+ 0x31 字节
首先,我想将其用于(亚马逊的 ListObjects 停顿)线程中止的目的是否安全?
其次,是否有一种安全的方法可以在没有异步线程中止的通用函数中执行此操作?
这是我所拥有的:
执行:
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);
}
}
}
}
来电:
response = Timeout<ListObjectsResponse>.Run(() => s3Client.ListObjects(request));