首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在已经运行的线程上执行函数?

如何在已经运行的线程上执行函数?
EN

Stack Overflow用户
提问于 2017-09-05 08:51:27
回答 2查看 753关注 0票数 4

我有一个线程A,它每5秒用一个计时器调用FunctionX()。但是有时我需要来自另一个线程线程B的FunctionX()的值,并且不能等待计时器的执行。我不能直接从线程B调用FunctionX(),因为它使用了一些外部组件,如果这些组件是从另一个线程调用的,而不是从原始线程调用的话。因此,FunctionX()必须始终运行在线程A上。如何在不等待计时器调用函数的情况下立即获得线程B上的FunctionX()值?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-09-05 09:07:34

这将取决于您正在使用的计时器类型,但是System.Threading.Timer类作为一个示例公开了一个Change方法,您可以使用该方法来说服计时器立即启动。下面是控制台应用程序测试工具中的一个示例:

代码语言:javascript
运行
复制
using System;
using System.Threading;

namespace FiringTheTimerTestHarness
{
    class Program
    {
        public static Thread _worker;
        public static Timer _timer;
        static void Main(string[] args)
        {
            _worker = new Thread(new ThreadStart(ThreadWorker));
            _worker.Start();
            var startTime = DateTime.Now;
            // Simulate the main UI thread being active doing stuff (i.e. if there's a Windows Forms app so we don't need anything to 
            // keep the app "alive"
            while (1==1)
            {
                Thread.Sleep(100);
                if (startTime.AddSeconds(30) < DateTime.Now)
                {
                    // Lets pretend that we need to fire the timer *now* so that we can get the result *now*
                    _timer.Change(0, 5000);
                }
            }
        }

        public static void ThreadWorker()
        {
            _timer = new Timer(new TimerCallback(DoStuffEveryFiveSeconds), null, 5000, 5000);
            while (1 == 1)
            {
                Thread.Sleep(100);
            }
        }

        public static void DoStuffEveryFiveSeconds(object state)
        {
            Console.WriteLine("{0}: Doing stuff", DateTime.Now);
        }
    }
}

您将看到如下所示的输出:

05/09/2017 10:04:44:做事情 05/09/2017 10:04:49:做事情 05/09/2017 10:04:54:做事情 05/09/2017 10:04:59:做事情 05/09/2017 10:05:04:做事情 05/09/2017 10:05:09:做事情 05/09/2017 10:05:09:做事情 05/09/2017 10:05:09:做事情 05/09/2017 10:05:09:做事情 05/09/2017 10:05:09:做事情

因此,计时器每隔5秒触发一次(按预期),然后开始每100毫秒启动一次(即“按需”)。这段代码位于一个人为的测试工具中,因此看起来有点奇怪,但其目的基本上是向您展示调用Change方法的结果。

票数 1
EN

Stack Overflow用户

发布于 2017-09-05 09:17:50

这里是,是我在评论中所说的一个大纲完全未经测试的 !!

代码语言:javascript
运行
复制
class FunctionXCaller
{
    private Task mTask;
    private BlockingCollection<TaskCompletionSource<TResult>> queue = new BlockingCollection<TaskCompletionSource<TResult>>();

    public FunctionXCaller()
    {
         mTask = Task.Run( () => WorkerMethod );
    }

    private void WorkerMethod()
    {
         while( !queue.IsCompleted )
         {
              TaskCompletionSource<TResult> tcs = queue.take();
              tcs.TrySetResult(FunctionX());
         }
    }


    public Task<TResult> CallXAsync()
    {
         TaskCompletionSource<TResult> tcs = new TaskCompletionSource<TResult>();
         queue.Add(tcs);
         return tcs.Task;
    }
}

注意:正如我已经写过的,这只是给你一个想法。有很多东西需要添加,比如关闭,清理,异常处理,.

其思想是,您可以从任何线程调用await FunctionXCallerInstance.CallXAsnc(),并让FunctionX始终在工作线程上执行。这里将是一个ThreadPool线程。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46050794

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档