我有一个线程A,它每5秒用一个计时器调用FunctionX()。但是有时我需要来自另一个线程线程B的FunctionX()的值,并且不能等待计时器的执行。我不能直接从线程B调用FunctionX(),因为它使用了一些外部组件,如果这些组件是从另一个线程调用的,而不是从原始线程调用的话。因此,FunctionX()必须始终运行在线程A上。如何在不等待计时器调用函数的情况下立即获得线程B上的FunctionX()值?
发布于 2017-09-05 09:07:34
这将取决于您正在使用的计时器类型,但是System.Threading.Timer类作为一个示例公开了一个Change方法,您可以使用该方法来说服计时器立即启动。下面是控制台应用程序测试工具中的一个示例:
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方法的结果。
发布于 2017-09-05 09:17:50
这里是,是我在评论中所说的一个大纲。完全未经测试的 !!
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线程。
https://stackoverflow.com/questions/46050794
复制相似问题