最近在业务中遇到这样一个需求:用一个方法不断向网络中的某个接口提交数据。
第一反应是使用定时任务。虽然能够解决问题,但始终觉得不够优雅。
C#中的网络包我选择了HttpLib这个开源库项目,比较简单,项目地址为https://github.com/j6mes/httplib/ 摘录一段代码如下:
Http.Get("https://jthorne.co.uk/httplib").OnSuccess(result =>
{
Console.Write(result);
}).OnFail(webexception =>
{
Console.Write(webexception.Message);
}).Go();
可以看到成功和失败都有一个回调方法。
于是想到这样一个方案:在回调中调用提交数据的方法。
OnSuccess回调的参数是一个Action<string>,OnFail的回调是Action<WebException>。于是我们定义两个变量
public Action<string> SuccessAction = new Action<string>(Success);
public Action<WebException> FailAction = new Action<WebException>(Fail);
我们先定义一个类来做这样的调用
class RemoteClass
{
public Action<string> SuccessAction = new Action<string>(Success);
public Action<WebException> FailAction = new Action<WebException>(Fail);
public static Action GetWebAction = new Action(getWeb);
public static void Success(string BookName)
{
Console.WriteLine("访问网络了"+Process.GetCurrentProcess().Threads.Count);
Thread.Sleep(5000);
GetWebAction();
}
public static void Fail(WebException ex)
{
Console.WriteLine(ex.Message);
Thread.Sleep(5000);
GetWebAction();
}
public static void getWeb()
{
//TODO 访问网络
}
}
先定义三个action ,这三个action的作用分别为:网络访问成功的回调SuccessAction,网络访问失败的回调FailAction和访问网络的GetWebAction。在这里无论远程地址访问成功还是失败都先sleep5秒,然后再调用远程访问方法。
现在让我们来来分别设置Http的回调。
sealed class Singleton
{
Action<string> SuccessAction ;
Action<WebException> FailAction;
private static readonly Singleton instance = null;
static Singleton()
{
instance = new Singleton();
}
private Singleton()
{
}
public static Singleton Instance
{
get
{
return instance;
}
}
public Singleton setSuccess(Action<String> action)
{
SuccessAction = action;
return Instance;
}
public Singleton setFail(Action<WebException> action)
{
FailAction = action;
return Instance;
}
public void run()
{
if (SuccessAction == null || FailAction == null)
throw new Exception("请先设置SuccessAction和FailAction");
Http.Get("https://www.baidu.com").OnSuccess(SuccessAction).OnFail(FailAction).Go();
}
}
这里我使用了一个单例来作为这个无限循环的起点。
main方法中这样调用
static void Main(string[] args)
{
RemoteClass thread = new RemoteClass();
Singleton.Instance.setSuccess(thread.SuccessAction).setFail(thread.FailAction).run();
Console.ReadKey();
}
最后修改下RemoteClass的getWeb方法
public static void getWeb()
{
Singleton.Instance.run();
}
完成的代码如下下
sealed class Singleton
{
Action<string> SuccessAction ;
Action<WebException> FailAction;
private static readonly Singleton instance = null;
static Singleton()
{
instance = new Singleton();
}
private Singleton()
{
}
public static Singleton Instance
{
get
{
return instance;
}
}
public Singleton setSuccess(Action<String> action)
{
SuccessAction = action;
return Instance;
}
public Singleton setFail(Action<WebException> action)
{
FailAction = action;
return Instance;
}
public void run()
{
if (SuccessAction == null || FailAction == null)
throw new Exception("请先设置SuccessAction和FailAction");
Http.Get("https://www.baidu.com").OnSuccess(SuccessAction).OnFail(FailAction).Go();
}
}
class RemoteClass
{
public Action<string> SuccessAction = new Action<string>(Success);
public Action<WebException> FailAction = new Action<WebException>(Fail);
public static Action GetWebAction = new Action(getWeb);
public static void Success(string BookName)
{
Console.WriteLine("访问了百度"+Process.GetCurrentProcess().Threads.Count);
Thread.Sleep(5000);
GetWebAction();
}
public static void Fail(WebException ex)
{
Console.WriteLine(ex.Message);
Thread.Sleep(5000);
GetWebAction();
}
public static void getWeb()
{
Singleton.Instance.run();
}
}
class Program
{
static void Main(string[] args)
{
RemoteClass thread = new RemoteClass();
Singleton.Instance.setSuccess(thread.SuccessAction).setFail(thread.FailAction).run();
Console.ReadKey();
}
}
运行起来
源码地址:点击打开链接 https://gitee.com/fengxici/Infinite-Loop-commit