C# 运行Func<;T>;在使用.Net的计时器上

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) {

我这样做是为了学习,需要一些帮助

目标是使用C#在计时器上执行Func。 计时器被抽象为另一个方法,但需要从主函数访问操作的返回值

考虑以下代码

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
事件

示例

在下面的示例中,为了保持简单,我没有使用async
Func
,但它没有改变一般概念。该示例在特定时间间隔内使用
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)-NuGet
System.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();
    }

}