C# 运行Func<;T>;在使用.Net的计时器上
我这样做是为了学习,需要一些帮助 目标是使用C#在计时器上执行Func。 计时器被抽象为另一个方法,但需要从主函数访问操作的返回值 考虑以下代码C# 运行Func<;T>;在使用.Net的计时器上,c#,.net,C#,.net,我这样做是为了学习,需要一些帮助 目标是使用C#在计时器上执行Func。 计时器被抽象为另一个方法,但需要从主函数访问操作的返回值 考虑以下代码 using System; using System.Timers; using System.Threading.Tasks; namespace actionexample { class Program { static void Main(string[] args) {
using System;
using System.Timers;
using System.Threading.Tasks;
namespace actionexample
{
class Program
{
static void Main(string[] args)
{
Func<string, string, Task> testFunc = async (f, n) =>
{
Console.WriteLine("Starting Action");
f += n;
Console.WriteLine(f);
await Task.Delay(100);
};
SubscribeToConfigAsync<string>("1", "2", testFunc);
Console.Write("END");
Console.ReadLine();
}
static void SubscribeToConfigAsync<T>(string feature, string name, Func<string, string, Task> action)
{
var timer = new Timer(5000);
timer.Elapsed += async (sender, e) => await action(feature, name);
timer.Start();
}
}
}
使用系统;
使用系统计时器;
使用System.Threading.Tasks;
名称空间操作示例
{
班级计划
{
静态void Main(字符串[]参数)
{
Func testFunc=async(f,n)=>
{
Console.WriteLine(“启动操作”);
f+=n;
控制台写入线(f);
等待任务。延迟(100);
};
下标betoconfigasync(“1”、“2”、testFunc);
控制台。写入(“结束”);
Console.ReadLine();
}
静态void SubscribeToConfigAsync(字符串功能、字符串名称、函数操作)
{
var定时器=新定时器(5000);
timer.appeased+=async(发送方,e)=>等待操作(特性,名称);
timer.Start();
}
}
}
我想在定时器勾选后访问Main()中Func生成的值,但不确定如何执行
我似乎无法让这个工作,任何帮助将不胜感激 您可以尝试将其添加为代理。参考下面的例子
myTimer.Tick += delegate { System.Console.WriteLine('Inside Delegate'); }
如果您只想访问由
计时器修改的值,那么只需将其作为实例而不是包含类
public class {
int Result { get; set; }
void TimerFunc(a, b) { Result = <some calculation>; }
Main() {
StartTimer();
while(true) { CheckResult(Result); }
}
}
如果您想根据某些配置值的更改停止并重新启动计时器
,则需要保留对计时器
实例的引用
Main() {
var oldConfigValues = <empty object>;
Timer t = null;
while(true){
var newConfigValues = GetDbConfigValues();
if(newConfigValues != oldConfigValues){
if(t != null){ <stop timer> }
t = InitializeTimer(newConfigValues);
oldConfigValues = newConfigValues;
}
}
}
Main(){
var oldConfigValues=;
定时器t=null;
while(true){
var newConfigValues=GetDbConfigValues();
if(新配置值!=旧配置值){
如果(t!=null){}
t=初始值(新配置值);
oldConfigValues=newConfigValues;
}
}
}
使用系统.集合.并发.并发队列如何
static void Main(string[] args) {
var AnswerQueue = new System.Collections.Concurrent.ConcurrentQueue<string>();
Func<string, string, Task> testFunc = async (f, n) => {
Console.WriteLine("Starting Action");
f += n;
Console.WriteLine(f);
AnswerQueue.Enqueue(f);
await Task.Delay(100);
};
SubscribeToConfigAsync<string>("1", "2", testFunc);
for (int j1 = 0; j1 < 12; ++j1) {
if (AnswerQueue.TryDequeue(out var ans)) {
Console.WriteLine($"{DateTime.Now.TimeOfDay}: {ans}");
}
Thread.Sleep(1000);
}
GlobalTimer.Stop();
Console.WriteLine("END");
}
public static System.Timers.Timer GlobalTimer;
static void SubscribeToConfigAsync<T>(string feature, string name, Func<string, string, Task> action) {
GlobalTimer = new System.Timers.Timer(2000);
GlobalTimer.Elapsed += async (sender, e) => await action(feature, name);
GlobalTimer.Start();
}
static void Main(字符串[]args){
var AnswerQueue=new System.Collections.Concurrent.ConcurrentQueue();
Func testFunc=async(f,n)=>{
Console.WriteLine(“启动操作”);
f+=n;
控制台写入线(f);
应答队列。排队(f);
等待任务。延迟(100);
};
下标betoconfigasync(“1”、“2”、testFunc);
对于(int j1=0;j1<12;++j1){
if(AnswerQueue.TryDequeue(out-var-ans)){
WriteLine($“{DateTime.Now.TimeOfDay}:{ans}”);
}
睡眠(1000);
}
GlobalTimer.Stop();
控制台。写入线(“结束”);
}
公共静态系统计时器计时器全局计时器;
静态void SubscribeToConfigAsync(字符串功能、字符串名称、函数操作){
GlobalTimer=新系统计时器计时器(2000);
GlobalTimer.Appead+=async(发送方,e)=>Wait操作(功能,名称);
GlobalTimer.Start();
}
在计时器已过事件中运行Func
,然后在结果准备就绪后,引发类似resultedy
的事件,并向所有使用者/订阅者报告结果
这意味着,最好创建一个类,如TaskAgent
,它负责接受Func
并在特定的时间间隔内运行Func
,并引发resultedy
事件
示例
在下面的示例中,为了保持简单,我没有使用asyncFunc
,但它没有改变一般概念。该示例在特定时间间隔内使用TaskAgent
运行Func
,并使用事件将结果报告给Main
方法:
using System;
using System.Linq;
using System.Timers;
名称空间示例{
班级计划{
静态void Main(字符串[]参数){
Func任务=(s)=>{
返回新字符串(s.ToCharArray().OrderBy(x=>Guid.NewGuid()).ToArray());
};
var taskAgent=新的taskAgent(任务,“样本”);
taskAgent.resultrady+=(s,e)=>Console.WriteLine(e);
taskAgent.Run();
Console.ReadLine();
taskAgent.Dispose();
}
}
类任务代理:IDisposable{
定时器;
Func任务;
字符串输入;
公共事件处理程序结果;
公共任务代理(Func任务,字符串输入){
this.task=任务;
这个输入=输入;
this.timer=new timer(){AutoReset=true,Interval=1000};
this.timer.Enabled=false;
this.timer.appeased+=(s,e)=>{
var结果=任务(输入);
结果?.Invoke(这个,结果);
};
}
public void Run(){timer.Start();}
public void Dispose(){timer.Dispose();}
}
}
我不清楚您的总体目标是什么,但您应该使用Microsoft的反应式框架(又称Rx)-NuGetSystem.Reactive
并使用System.Reactive.Linq添加代码>-这将使您的代码更加简单。试试这个:
Func<string, string, string> testFunc = (f, n) =>
{
Console.WriteLine("Starting Action");
return f + n;
};
Observable
.Interval(TimeSpan.FromSeconds(5.0))
.Select(x => testFunc("1", "2"))
.Subscribe(x => Console.WriteLine(x));
Console.Write("END");
Console.ReadLine();
在控制台中生成以下内容:
0
01
012
0123
01234
The last result was: 01234
END
0
01
012
0123
01234
最后的结果是:01234
结束
为什么不想在TimerTick函数中使用一个以上的操作作为参数
using System;
using System.Timers;
using System.Threading.Tasks;
namespace actionexample
{
class Program
{
static void Main(string[] args)
{
Action<string, string> resultHandler = (a,b,) => {
//Do something
}
Func<string, string, Action<string, string>, Task> testFunc = async (f, n, h) =>
{
Console.WriteLine("Starting Action");
f += n;
Console.WriteLine(f);
await Task.Delay(100);
h(f, n);
};
SubscribeToConfigAsync<string>("1", "2", testFunc);
Console.Write("END");
Console.ReadLine();
}
static void SubscribeToConfigAsync<T>(string feature, string name, Func<string, string, Action<string, string>, Task> action, Action<string, string> handler)
{
var timer = new Timer(5000);
timer.Elapsed += async (sender, e) => await action(feature, name, handler);
timer.Start();
}
}
使用系统;
使用系统计时器;
使用System.Threading.Tasks;
名称空间操作示例
{
班级计划
{
静态void Main(字符串[]参数)
{
Action resultHandler=(a,b,)=>{
//做点什么
}
Func testFunc=async(f,n,h)=>
{
Console.WriteLine(“启动操作”);
f+=n;
控制台写入线(f);
等待任务。延迟(100);
h(f,n);
};
下标betoconfigasync(“1”、“2”、testFunc);
控制台。写入(“结束”);
Console.ReadLine();
}
静态无效订阅Betoconfigasync(字符串特征,stri
var last_result =
Observable
.Interval(TimeSpan.FromSeconds(1.0))
.Take(5)
.Scan("", (a, x) => a + x.ToString())
.Do(z => Console.WriteLine(z))
.Wait();
Console.WriteLine("The last result was: " + last_result);
Console.WriteLine("END");
0
01
012
0123
01234
The last result was: 01234
END
using System;
using System.Timers;
using System.Threading.Tasks;
namespace actionexample
{
class Program
{
static void Main(string[] args)
{
Action<string, string> resultHandler = (a,b,) => {
//Do something
}
Func<string, string, Action<string, string>, Task> testFunc = async (f, n, h) =>
{
Console.WriteLine("Starting Action");
f += n;
Console.WriteLine(f);
await Task.Delay(100);
h(f, n);
};
SubscribeToConfigAsync<string>("1", "2", testFunc);
Console.Write("END");
Console.ReadLine();
}
static void SubscribeToConfigAsync<T>(string feature, string name, Func<string, string, Action<string, string>, Task> action, Action<string, string> handler)
{
var timer = new Timer(5000);
timer.Elapsed += async (sender, e) => await action(feature, name, handler);
timer.Start();
}
}