我正在寻找一个通用的尝试,并在C#中使用超时重试.基本上,我想要以下内容:
bool stopTrying = false;
DateTime time = DateTime.Now;
while (!stopTrying)
{
try
{
//[Statement to Execute]
}
catch (Exception ex)
{
if (DateTime.Now.Subtract(time).Milliseconds > 10000)
{
stopTrying = true;
throw ex;
}
}
}
Run Code Online (Sandbox Code Playgroud)
在上面的例子中,我等待10秒,但它应该是基于参数的变量超时.我不想在需要使用它的任何地方重复这个完整的代码.我的代码中有多个地方,它们不是API中内置的超时,如果应用程序尚未准备好执行语句,我将遇到异常.这也可以避免在这些声明之前对我的应用程序中的延迟进行硬编码.
澄清:有关陈述可能类似于转让.如果我使用委托和method.Invoke,是不是作用在委托内的调用而不是原始方法?
我有一个Parallel.Foreach循环
var options = new ParallelOptions();
options.MaxDegreeOfParallelism = 1;
Parallel.ForEach(urlTable.AsEnumerable(),drow =>
{
using (var WCC = new MasterCrawlerClass())
{
WCC.MasterCrawlBegin(drow);
}
}
Run Code Online (Sandbox Code Playgroud)
这个循环调用类并循环遍历我的所有DataRows,但是每个数据行都会执行DataTable填充,或者对MySQL DB执行更新命令.我对这两个代码的代码如下.
private static DataTable DTTable(string mysqlQuery, string queryName)
{
DataTable DTTableTable = new DataTable();
try
{
MySqlDataAdapter DataDTTables = new MySqlDataAdapter(mysqlQuery, MySQLProcessing.MySQLStatic.Connection);
DataTable DataDTTablesDT = new DataTable();
DataDTTables.SelectCommand.CommandTimeout = 240000;
DataDTTables.Fill(DataDTTablesDT);
DTTableTable = DataDTTablesDT;
}
catch (Exception ex)
{
GenericLogging("Failed MySQLquery: " + ex.Message.ToString(), "MySQLProcessor", "DTTable", "", "MysqlError", "", queryName, mysqlQuery);
}
return DTTableTable;
}
Run Code Online (Sandbox Code Playgroud)
private static …Run Code Online (Sandbox Code Playgroud) 我System.ComponentModel.BackgroundWorker在我的WPF应用程序中使用.
如何设置超时了BackgroundWorker?
原始方法调用如下:
public string AskAPI(string uri)
{
return api.Query(uri);
}
Run Code Online (Sandbox Code Playgroud)
其中api只是一个导入的dll引用.
现在我想在AskAPI方法中添加一个超时功能,这样如果api.Query需要的时间比30秒长,AskAPI会抛出异常.
似乎我无法让它工作.谁能分享他们对此的看法?
谢谢!
我目前正在为现有应用程序编写基于Web服务的前端.为此,我使用WCF LOB适配器SDK,它允许创建自定义WCF绑定,将外部数据和操作公开为Web服务.
SDK提供了一些实现的接口,并且它们的一些方法是时间约束的:实现期望在指定的时间跨度内完成其工作或抛出TimeoutException.
调查让我想到了" 实现C#通用超时 "的问题,明智地建议使用工作线程.有了这些知识,我可以写:
public MetadataRetrievalNode[] Browse(string nodeId, int childStartIndex,
int maxChildNodes, TimeSpan timeout)
{
Func<MetadataRetrievalNode[]> work = () => {
// Return computed metadata...
};
IAsyncResult result = work.BeginInvoke(null, null);
if (result.AsyncWaitHandle.WaitOne(timeout)) {
return work.EndInvoke(result);
} else {
throw new TimeoutException();
}
}
Run Code Online (Sandbox Code Playgroud)
但是,如果工作线程超时,则不清楚如何处理工作线程.人们可以忘记它,就像上面的代码那样,或者可以中止它:
public MetadataRetrievalNode[] Browse(string nodeId, int childStartIndex,
int maxChildNodes, TimeSpan timeout)
{
Thread workerThread = null;
Func<MetadataRetrievalNode[]> work = () => {
workerThread = Thread.CurrentThread;
// Return computed …Run Code Online (Sandbox Code Playgroud) 如果方法在一段有限的时间内没有完成,我需要停止执行.
要做这项工作,我可以这样使用Thread.Abort方法:
void RunWithTimeout(ThreadStart entryPoint, int timeout)
{
var thread = new Thread(() =>
{
try
{
entryPoint();
}
catch (ThreadAbortException)
{ }
}) { IsBackground = true };
thread.Start();
if (!thread.Join(timeout))
thread.Abort();
}
Run Code Online (Sandbox Code Playgroud)
鉴于我使用的是.NET 3.5,还有更好的方法吗?
编辑:跟随我的评论entryPoint,但我正在寻找一个好方法entryPoint.
void entryPoint()
{
// I can't use ReceiveTimeout property
// there is not a ReceiveTimeout for the Compact Framework
socket.Receive(...);
}
Run Code Online (Sandbox Code Playgroud) 重复:杀死一个帖子(C#)
如果我在3秒内没有收到回复,我需要一种方法来杀死这个线程.
完成此任务的最佳方法是什么?它不一定必须与thread/threadstart一起使用,这就是我到目前为止所使用的内容.
如果运行时间过长,我怎样才能中止方法的执行?
例如
string foo = DoSomethingComplex();
Run Code Online (Sandbox Code Playgroud)
但如果DoSomethingComplex()花的时间太长(20秒就可以说).然后只需将foo设为"";
我有一个(可能)冗长的操作a,我想对其施加限制时间约束t(以毫秒为单位)。如果操作a 的完成时间少于t毫秒,那么我将返回操作a的答案;否则我想中止操作并返回一个正确的错误代码,说明超出了时间限制。
我怎样才能在 C# 中完成这个?如果您有其他与语言无关的想法,请随时分享?
看到这里的代码.谁能告诉我这意味着什么?
Action wrappedAction = () =>
{
threadToKill = Thread.CurrentThread;
action();
};
Run Code Online (Sandbox Code Playgroud)
我们可以用.net v2.0编写这样的代码吗?