简体   繁体   English

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

[英]Call delegate on main thread from asynchronous task

This seems simple enough... wanting to do this in .NET 3.5 (CF compatible if possible). 这似乎很简单...想要在.NET 3.5(如果可能,则兼容CF)中执行此操作。

I want to call a function, and pass it a callback function that it fires upon completion. 我想调用一个函数,并将其传递给回调函数,该函数将在完成时触发。 How is this done? 怎么做?

Example code: 示例代码:

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();
 }

I agree with the question in the comments, why do you want to execute the delegate on the main thread? 我同意注释中的问题,为什么要在主线程上执行委托? That said, if you insist it can be done in a couple of ways, both of which require you to implement some infrastructure for your main thread to allow it. 就是说,如果您坚持可以用两种方法完成这两种方法,那么这两种方法都需要您为主线程实现某种基础结构以允许它。

The simplest to understand is to write some explicit code to coordinate. 最简单的理解是编写一些明确的代码来进行协调。 For example, taking your original code: 例如,使用原始代码:

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);
    }
 }

Note that this will block your main thread while the other thread does its work. 请注意,这将阻塞您的主线程,而另一个线程则起作用。 This is pretty much always the wrong thing to do, but does literally accomplish your request. 这几乎总是错误的做法,但是确实可以完成您的请求。

If you want the main thread to continue working on something else, then it needs to be implemented to do that something else while also periodically checking for completion of your task, at which point it would invoke the delegate. 如果希望主线程继续执行其他操作,则需要将其实现为执行其他操作,同时还定期检查任务是否完成,这时它将调用委托。 WinForms and WPF programs have a message-pumping loop that is also used for this purpose. WinForms和WPF程序具有一个消息泵送循环,该循环也用于此目的。 If you want the same behavior in your non-GUI program, you'll have to reinvent that particular wheel. 如果要在非GUI程序中实现相同的行为,则必须重新发明该特定的轮子。

On the bright side, if you do that and at the same time implement a custom SynchronizationContext that works with your implementation, then you get the other cross-thread features of .NET essentially for free. 从好的方面来说,如果您这样做并且同时实现了一个可与您的实现一起使用的自定义SynchronizationContext,那么您基本上可以免费获得.NET的其他跨线程功能。 On the not-so-bright side, doing all that is a lot of work. 在不那么光明的一面,尽一切是大量的工作。

Are you really really sure you need this behavior? 您真的确定您需要这种行为吗? If you explain in more detail what you're actually trying to accomplish, you might get a better answer. 如果您更详细地说明您实际要完成的工作,则可能会得到更好的答案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM