C# 服务不是';t正在运行Task.run

C# 服务不是';t正在运行Task.run,c#,multithreading,windows-services,C#,Multithreading,Windows Services,我已经编写了一个windows服务。 下面是类中定义的全局变量: private static TimeSpan pollingInterval; private static Thread regenerationThread; private static ManualResetEvent quitThreadEvent; private static ConcurrentQueue<KeyValuePair<string, string>> queue = new

我已经编写了一个windows服务。 下面是类中定义的全局变量:

private static TimeSpan pollingInterval;
private static Thread regenerationThread;
private static ManualResetEvent quitThreadEvent;
private static ConcurrentQueue<KeyValuePair<string, string>> queue = new ConcurrentQueue<KeyValuePair<string, string>>();

下面是上面提到的doStart方法:

internal static void doStart()
{   
    queue.Enqueue(new KeyValuePair<string, string>("user1", "password1"));
    queue.Enqueue(new KeyValuePair<string, string>("user2", "password2"));
    queue.Enqueue(new KeyValuePair<string, string>("user3", "password3"));
    while (!quitThreadEvent.WaitOne(pollingInterval))
    {
        // tempList isn't empty, I checked it putting logs here.
        if (tempList.Length != 0)
        {
            var temp = new KeyValuePair<string, string>();
            if (queue.TryDequeue(out temp))
            {
                string username = temp.Key;
                string password = temp.Value;
                // Method comes till here but doesn't execute the statement below and directly reach to end WriteToFile method.
                Task.Run(async () =>
                {
                    await tempFunc(username, password);
                    queue.Enqueue(new KeyValuePair<string, string>(username, password));
                });
            }
        }
        WriteToFile("End of Method");
    }
}
内部静态void doStart()
{   
排队(新的KeyValuePair(“user1”、“password1”);
排队(新的KeyValuePair(“user2”、“password2”);
排队(新的KeyValuePair(“user3”、“password3”);
而(!quitThreadEvent.WaitOne(pollingInterval))
{
//圣殿骑士不是空的,我把日志放在这里检查过了。
if(templast.Length!=0)
{
var temp=新的KeyValuePair();
if(queue.TryDequeue(out temp))
{
字符串用户名=临时密钥;
字符串密码=临时值;
//方法一直到这里,但不执行下面的语句并直接到达end WriteToFile方法。
Task.Run(异步()=>
{
等待tempFunc(用户名、密码);
排队(新的KeyValuePair(用户名、密码));
});
}
}
WriteToFile(“方法结束”);
}
}

我不确定为什么
任务.Run
不起作用。我已经放置了日志,但它没有显示任何错误。我尝试将日志放入
任务中。运行
,但它不显示这些日志。是我启动线程然后调用任务的原因。在线程内运行

我已经重写了您的代码,只使用异步/等待模式

private static TimeSpan pollingInterval;
private static Task regenerationTask;
private static CancellationTokenSource quitThreadEvent;
private static ConcurrentQueue<KeyValuePair<string, string>> queue = new ConcurrentQueue<KeyValuePair<string, string>>();

internal static void Start()
{
    pollingInterval = TimeSpan.FromSeconds(100);
    quitThreadEvent = new CancellationTokenSource();
    regenerationTask = ExecuteAsync( quitThreadEvent.Token );
}

尽管您的代码并不像人们所说的那样是一种很好的实现方式,但是您的代码也应该可以工作,除非您的代码在其他地方有问题。我在当地试过,效果不错。但是“while(!quitThreadEvent.WaitOne(pollingInterval))”会阻止内部代码执行“pollingInterval”(100秒),除非您在其他地方设置了quitThreadEvent。确保你的程序不会在100秒前结束。如果它提前结束,您可能看不到执行结果。 这是一个工作版本代码:

    internal static void Start()
    {
        pollingInterval = TimeSpan.FromSeconds(1);
        quitThreadEvent = new ManualResetEvent(false);
        regenerationThread = new Thread(doStart);
        regenerationThread.Start();
    }

    internal static void doStart()
    {
        queue.Enqueue(new KeyValuePair<string, string>("user1", "password1"));
        queue.Enqueue(new KeyValuePair<string, string>("user2", "password2"));
        queue.Enqueue(new KeyValuePair<string, string>("user3", "password3"));
        while (!quitThreadEvent.WaitOne(pollingInterval))
        {
            // tempList isn't empty, I checked it putting logs here.
            if (true)
            {
                var temp = new KeyValuePair<string, string>();
                if (queue.TryDequeue(out temp))
                {
                    string username = temp.Key;
                    string password = temp.Value;
                    // Method comes till here but doesn't execute the statement below and directly reach to end WriteToFile method.
                    Task.Run(async () =>
                    {
                        await tempFunc(username, password);
                        queue.Enqueue(new KeyValuePair<string, string>(username, password));
                    });
                }
                Console.WriteLine("End of the method.");
                break;
            }
        }
    }

    internal static async Task tempFunc(string userName, string pwd)
    {
        Console.WriteLine($"UserName = {userName}, Pwd = {pwd}");
        await Task.Delay(1000);
    }

    static void Main(string[] args)
    {
        Start();
        Thread.Sleep(5000);
    }
内部静态无效开始()
{
pollingInterval=从秒开始的时间跨度(1);
quitThreadEvent=新的ManualResetEvent(错误);
再生线程=新线程(doStart);
reseactionThread.Start();
}
内部静态void doStart()
{
排队(新的KeyValuePair(“user1”、“password1”);
排队(新的KeyValuePair(“user2”、“password2”);
排队(新的KeyValuePair(“user3”、“password3”);
而(!quitThreadEvent.WaitOne(pollingInterval))
{
//圣殿骑士不是空的,我把日志放在这里检查过了。
如果(真)
{
var temp=新的KeyValuePair();
if(queue.TryDequeue(out temp))
{
字符串用户名=临时密钥;
字符串密码=临时值;
//方法一直到这里,但不执行下面的语句并直接到达end WriteToFile方法。
Task.Run(异步()=>
{
等待tempFunc(用户名、密码);
排队(新的KeyValuePair(用户名、密码));
});
}
WriteLine(“方法结束”);
打破
}
}
}
内部静态异步任务tempFunc(字符串用户名,字符串pwd)
{
WriteLine($“UserName={UserName},Pwd={Pwd}”);
等待任务。延迟(1000);
}
静态void Main(字符串[]参数)
{
Start();
睡眠(5000);
}

`

为什么不使用
Task.Run()
而不是线程?不需要任务。在这个上下文中运行我没有理解。您是否建议改为
recreationthread=newthread(doStart)
再生线程.Start()语句。使用
Task.Run()
启动方法
doStart
@Clintyour
DoStart()
可以是一个
异步任务DoTask()
@SirRufo,实际上我希望
tempFunc
方法被异步调用多次,所以我认为
Task.Run
是一种正确的方法吗?或者我遗漏了什么?
等待任务。延迟(pollingInterval,cancellationToken)。配置等待(false)这到底是做什么的?假设我有一个
async
方法,我必须把
wait
放在其中,但我不想等待其他任何东西。因此,如果我在上面的语句中把pollingInterval设置为0,那么它能完成这个任务吗?试图理解我提到的语句。实际上谈论
tempFunc
,如果我在
tempFunc
中有一堆语句,我只是不想在任何地方等待并异步执行该方法,使
等待任务。Dealy(0)
会为我做这件事吗?@sporty_1993
任务。延迟(…)
将等待给定的延迟,但在cacellationToken处于取消状态时引发异常。这有点像你的活动
ConfigureAwait(false)
将导致任务无法捕获当前同步上下文,并将在工作线程上继续执行。
task.Delay(0)。ConfigureAwait(false)
与您不写任何内容时相同。如果要继续工作线程,则必须
等待Task.Delay(1).ConfigureAwait(false)wait Task.Deay()
处停止,等待
pollingInterval
,然后继续执行,对吗?但是这里
await tempFunc(用户名、密码)
之后,它将在主线程中继续运行,同时运行
tempFunc
我正在设置quitThreadEvent,只有当我停止服务时。但是仍然没有调用该方法,我不知道为什么。
internal static async Task ExecuteAsync(CancellationToken cancellationToken)
{   
    queue.Enqueue(new KeyValuePair<string, string>("user1", "password1"));
    queue.Enqueue(new KeyValuePair<string, string>("user2", "password2"));
    queue.Enqueue(new KeyValuePair<string, string>("user3", "password3"));
    while ( true )
    {
        await Task.Delay( pollingInterval, cancellationToken ).ConfigureAwait( false );
        // tempList isn't empty, I checked it putting logs here.
        if (tempList.Length != 0)
        {
            var temp = new KeyValuePair<string, string>();
            if (queue.TryDequeue(out temp))
            {
                string username = temp.Key;
                string password = temp.Value;

                // fire and forget task - we do not want to await
                // so we do not need to store the task instance
                _ = WorkWithAsync(username, password);
            }
        }
        WriteToFile("End of Method");
    }
}

private static async Task WorkWithAsync( string username, string password )
{
    await tempfunc( username, password ).ConfigureAwait( false );
    queue.Enqueue(new KeyValuePair<string, string>(username, password));
}
internal static void Stop()
{
    quitThreadEvent.Cancel();
    regenerationTask.Wait();
}

internal static async Task StopAsync()
{
    quitThreadEvent.Cancel();
    await regenerationTask;
}
    internal static void Start()
    {
        pollingInterval = TimeSpan.FromSeconds(1);
        quitThreadEvent = new ManualResetEvent(false);
        regenerationThread = new Thread(doStart);
        regenerationThread.Start();
    }

    internal static void doStart()
    {
        queue.Enqueue(new KeyValuePair<string, string>("user1", "password1"));
        queue.Enqueue(new KeyValuePair<string, string>("user2", "password2"));
        queue.Enqueue(new KeyValuePair<string, string>("user3", "password3"));
        while (!quitThreadEvent.WaitOne(pollingInterval))
        {
            // tempList isn't empty, I checked it putting logs here.
            if (true)
            {
                var temp = new KeyValuePair<string, string>();
                if (queue.TryDequeue(out temp))
                {
                    string username = temp.Key;
                    string password = temp.Value;
                    // Method comes till here but doesn't execute the statement below and directly reach to end WriteToFile method.
                    Task.Run(async () =>
                    {
                        await tempFunc(username, password);
                        queue.Enqueue(new KeyValuePair<string, string>(username, password));
                    });
                }
                Console.WriteLine("End of the method.");
                break;
            }
        }
    }

    internal static async Task tempFunc(string userName, string pwd)
    {
        Console.WriteLine($"UserName = {userName}, Pwd = {pwd}");
        await Task.Delay(1000);
    }

    static void Main(string[] args)
    {
        Start();
        Thread.Sleep(5000);
    }