从异步任务调用主线程上的委托

时间:2014-10-15 15:19:30

标签: c# .net multithreading

这看起来很简单......想在.NET 3.5中执行此操作(如果可能,请兼容CF)。

我想调用一个函数,并传递一个它在完成时触发的回调函数。这是怎么做到的?

示例代码:

public static void downloadTemplateDataAsync(int officeID, int? workbookID, TemplateType templateType, int? templateID, TemplateRequestDelegate callback)
{
    Template t = null;
    System.Threading.Thread callingThread = System.Threading.Thread.CurrentThread;
    new System.Threading.Thread(() =>
    {
        t = downloadTemplateData(officeID, workbookID, templateType, templateID);

        // Dispatch callback
        callback.Invoke(t);
    }).Start();
 }

1 个答案:

答案 0 :(得分:1)

我同意评论中的问题,为什么要在主线程上执行委托?也就是说,如果你坚持认为它可以通过几种方式完成,这两种方式都要求你为主线程实现一些基础设施以允许它。

最简单的理解是编写一些显式代码来进行协调。例如,采用原始代码:

public static void downloadTemplateDataAsync(int officeID, int? workbookID, TemplateType templateType, int? templateID, TemplateRequestDelegate callback)
{
    Template t = null;
    object o = new object();
    System.Threading.Thread callingThread = System.Threading.Thread.CurrentThread;
    new System.Threading.Thread(() =>
    {
        t = downloadTemplateData(officeID, workbookID, templateType, templateID);

        // Signal completion
        lock (o) Monitor.Pulse(o);
    }).Start();

    lock (o) Monitor.Wait(o);
    callback.Invoke(t);
    }
 }

请注意,这将阻止主线程,而另一个线程完成其工作。这几乎总是错误的做法,但确实完成了你的要求。

如果您希望主线程继续处理其他内容,则需要实现它以执行其他操作,同时还定期检查您的任务是否完成,此时它将调用该委托。 WinForms和WPF程序有一个消息循环,也用于此目的。如果你想在非GUI程序中使用相同的行为,你将不得不重新发明那个特定的轮子。

从好的方面来说,如果你这样做并同时实现一个与你的实现一起使用的自定义SynchronizationContext,那么你基本上可以免费获得.NET的其他跨线程功能。在不那么光明的一面,做所有这些很多的工作。

你真的确定你需要这种行为吗?如果你更详细地解释一下你实际想要完成什么,你可能会得到一个更好的答案。