2011-10-11 202 views
1

我是新来的异步编程。我有一个被调用的异步方法的C#DLL,接受函数指针(委托)并在计算“结果”后调用此回调函数。异步回调

public delegate void CreatedDelegate(Foo result); 

public void CreateAsync(CreatedDelegate createdCallback) 
    { 
     Task t = Task.Factory.StartNew(() => 
             { 
             Foo result = ... 
             createdCallback(result); 
             }); 
    } 

类型的代表回调“CreatedDelegate”是(在我的情况下)的函数的指针的C++/CLI方法与结果的工作原理。

void CreatedCallback(Foo^ result) 
{ 
    // do something with result 
} 

所以这个异步概念似乎在大多数情况下工作得很好,但有时候我会遇到一些错误。如果使用不同的计算工作多次调用函数“CreateAsync”,那么我怎么能实现它,调用“CreatedCallback”的结果调用是否与最初调用“CreateAsync”的顺序相同?为了使它更清楚:即使后续调用“CreateAsync”的速度更快,并且实际上会更早地调用回调,第一次调用“CreateAsync”应导致第一次调用“CreatedCallback”。

也许这可以通过一次只允许一个活动的新线程在异步“CreateAsync”中完成?

+0

这不是如何线程的作品,从一个以上的,并让他们以不可预知的方式完成无序的设计。如果这是一个问题,请使用生产者/消费者模式。 –

回答

1

要处理的回调,从而,你需要执行的工作项目排队一些。最简单的方法可能是使用BlockingCollection类型(请参阅MSDN documentation)。

而不是调用回调,您CreateAsync方法将(与回调一起)添加任务到队列:

// Queue to keep tasks and their callbacks 
private BlockingCollection<Tuple<Task<Foo>, CreatedDelegate>> 
    queue = new BlockingCollection<Tuple<Task<Foo>, CreatedDelegate>>() 

public void CreateAsync(CreatedDelegate createdCallback) { 
    Task<Foo> t = Task.Factory.StartNew(() => { 
     Foo result = ... 
     return result; }); 
    queue.Add(Tuple.Create(t, createdCallback)); 
    // .. 
} 

这只会任务和回调添加到队列 - 实际调用回调,你需要的是等待队列中的任务的另一个任务(按它们被添加的顺序),并调用回调:

Task.Factory.StartNew(() => { 
    while(true) { // while you keep calling 'CreateAsync' 
    // Get next task (in order) and its callback 
    Tuple<Task<Foo>, CreatedDelegate> op = queue.Take(); 
    // Wait for the result and give it to callback 
    op.Item2(op.Item1.Result); 
    } 
} 
+0

Thx,我会尽快尝试。 – Michbeckable

0

如果顺序很重要,那么使用线程可能会更好:

thread queue = empty 
for each task 
{ 
    if there are no free 'cpu' 
    wait on first thread in queue 
    remove thread from queue 
    call delegate 

    create thread 
    add thread to queue 
} 

while queue has threads 
    wait on first thread in queue 
    remove thread from queue 
    call delegate 
+0

Thx,这可能是重点。这是否被集成在“CreateAsync”中,摆脱了Task.Factory.StartNew ...? – Michbeckable

+0

您的CreateAsync是“创建线程/添加到队列”位。 – Skizz