.NET 指南:超时的使用

使用超时来指定调用者将要在一个方法的调用被完成时的最大等待时间。

超时可能为方法的调用而获取一个参数表,如下所示。

Visual Basic
server.PerformOperation(timeout)
C#
server.PerformOperation(timeout);

另外,超时还能够与 server 类的属性一样被使用,如下所示。

Visual Basic
server.Timeout = timeout
server.PerformOperation()
C#
server.Timeout = timeout;
server.PerformOperation();

你应该使用第一种方式,因为操作与超时之间的关联是更加清晰的。如果 server 类被设计成一个由可视化设计者而被使用的组件,那么基于属性的方式可能是更好的。

在历史上,超时是通过整数而被呈现的。但是整数的超时是难以使用的,因为它没有明显的超时单位,并且也难以把时间单位转化成公共的毫秒。

一个更好的方式就是使用 TimeSpan 结构来作为超时的类型。TimeSpan 解决了在前面所提及的整数超时的问题。下列代码范例说明了如何使用 TimeSpan 类型的超时。

Visual Basic
Public Class Server
   Public Sub PerformOperation(timeout As TimeSpan)
      ' 在这里插入方法的代码、
      Console.WriteLine("performing operation with timeout {0}", _
        timeout.ToString())
   End Sub
End Class
C#
public class Server
{
   public void PerformOperation(TimeSpan timeout)
   {
      // 在这里插入方法的代码。
      Console.WriteLine("performing operation with timeout {0}", 
        timeout.ToString());
   }
}

如果超时被设置成 TimeSpan(0),并且操作没有立即被完成,那么方法就应该抛出一个异常。如果超时被设置成 TimeSpan.MaxValue,那么操作应该始终等待,这是与没有设置超时是一样的。一个 server 类不必支持这些值中的任何一个,但是在指定了一个不被支持的超时值的时候,它就应该抛出一个 ArgumentException 异常。

如果超时出现过期并且抛出了一个异常,那么 server 类就应该取消底层的操作。

如果使用了一个默认的超时,并且用户没有对它进行指定,那么 server 类就应该包括一个静态的属性来指定被使用的超时。下列代码范例示范了一个指定了默认超时的属性实现。

Visual Basic
Class ServerWithDefault
   Private Shared defaultTimeout As New TimeSpan(1000)
   
   Public Overloads Sub PerformOperation()
      Me.PerformOperation(DefaultOperationTimeout)
   End Sub 
   
   Public Overloads Sub PerformOperation(timeout As TimeSpan)
      ' 在这里插入代码。
      Console.WriteLine("performing operation with timeout {0}", _
        timeout.ToString())
   End Sub 
   
   Public Shared ReadOnly Property DefaultOperationTimeout As TimeSpan
      Get
         Return defaultTimeout
      End Get
   End Property
End Class
C#
class ServerWithDefault
{
   static TimeSpan defaultTimeout = new TimeSpan(1000); 

   public void PerformOperation()
   {
      this.PerformOperation(DefaultOperationTimeout);
   }

   public void PerformOperation(TimeSpan timeout)
   {
      // 在这里插入代码。
      Console.WriteLine("performing operation with timeout {0}", 
        timeout.ToString());
   }

   public static TimeSpan DefaultOperationTimeout
   {
      get
      {
         return defaultTimeout;
      }
   }
}

至于那些不能够把超时解析成 TimeSpan 的类型,应该把超时四舍五入成最接近的并且是能够被容纳的时间间隔。例如,一个只能够等待一秒增量的类型就应该被四舍五入成最接近的秒数。这个规则的一个例外就是在一个值被四舍五入成零值的时候。在这种情况下,超时应该被四舍五入成最小的可被接受的超时值。并且对零值进行四舍五入还能够防止由于零值的超时所导致的 100% 的处理器利用的忙碌等待循环。

另外,建议你在使用超时的过期来替代返回一个错误码的时候抛出一个异常。超时的过期表示操作并没有成功地被完成,所以它应该与任何其他的运行时错误一样被对待并且被处理。关于更多信息,请参考:[异常设计指南]。

在一个能够超时的异步操作中,应该调用一个回调函数并且在操作的结果第一次被访问的时候抛出一个异常。这种情况在下列代码范例中被说明。

Visual Basic
Sub OnReceiveCompleted(ByVal sender As System.Object, ByVal asyncResult As ReceiveCompletedEventArgs)
   Dim queue As MessageQueue = CType(sender, MessageQueue)
   ' 如果 BeginReceive 方法出现超时,那么下列代码将会抛出一个异常。
   Dim message As Message = queue.EndReceive(asyncResult.AsyncResult)
   Console.WriteLine(("Message: " + CStr(message.Body)))
   queue.BeginReceive(New TimeSpan(1, 0, 0))
End Sub
C#
void OnReceiveCompleted(Object sender, ReceiveCompletedEventArgs asyncResult)
{
   MessageQueue queue = (MessageQueue) sender;
   // 如果 BeginReceive 方法出现超时,那么下列代码将会抛出一个异常。
   Message message = queue.EndReceive(asyncResult.AsyncResult);
   Console.WriteLine("Message: " + (string)message.Body);
queue.BeginReceive(new TimeSpan(1,0,0));
}

转载于:https://www.cnblogs.com/Laeb/archive/2007/02/05/641026.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
.net C#线程超时的解决方案,使用的时候在被调线程入口调用一下这个方法就可以。更多详细代码见附件 Report.RegisterThread(Report.GetCurrentWin32ThreadID(),Thread.CurrentThread); #region 获取当取线程的ThreadID [DllImport("Kernel32", EntryPoint = "GetCurrentThreadId", ExactSpelling = true)] public static extern Int32 GetCurrentWin32ThreadID(); #endregion #region 登记访问任务子线程 /// /// 访问任务子线程 /// public static Hashtable TaskThreadIDTable = Hashtable.Synchronized(new Hashtable()); private static int[] TaskThreadIDs { get { int[] IDs = new int[TaskThreadIDTable.Keys.Count]; TaskThreadIDTable.Keys.CopyTo(IDs, 0); return IDs; } } public static void RegisterThread(int _threadid, System.Threading.Thread thread) { if (!TaskThreadIDTable.ContainsKey(_threadid)) TaskThreadIDTable.Add(_threadid, thread); if (!ExitInvalidThreadLoopRunning) { Thread ExitInvalidThreadLoopThread = new Thread(new ThreadStart(ExitInvalidThreadLoop)); ExitInvalidThreadLoopThread.Priority = ThreadPriority.AboveNormal; ExitInvalidThreadLoopThread.Start(); } } #endregion #region 关闭,退出超时的用户线程 private static DateTime ExitInvalidThreadLoop_LastRunTime = DateTime.Now.Subtract(new TimeSpan(1, 0, 0, 0, 0)); private static bool ExitInvalidThreadLoopRunning { get { return DateTime.Now.Subtract(ExitInvalidThreadLoop_LastRunTime).TotalMinutes 10) { try { Thread thread = (Thread)TaskThreadIDTable[t.Id]; thread.Abort(); } catch { } t.Dispose(); } } #endregion } #endregion

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值