Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从异步任务调用主线程上的委托_C#_.net_Multithreading - Fatal编程技术网

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

C# 从异步任务调用主线程上的委托,c#,.net,multithreading,C#,.net,Multithreading,这似乎很简单。。。希望在.NET3.5中实现这一点(如果可能,请与CF兼容) 我想调用一个函数,并向它传递一个回调函数,该函数在完成时启动。这是怎么做到的 示例代码: public static void downloadTemplateDataAsync(int officeID, int? workbookID, TemplateType templateType, int? templateID, TemplateRequestDelegate callback) { Templa

这似乎很简单。。。希望在.NET3.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();
 }

我同意评论中的问题,为什么要在主线程上执行委托?这就是说,如果您坚持可以通过两种方式来实现,这两种方式都需要您为主线程实现一些基础设施来实现

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

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的其他跨线程功能。从不那么乐观的方面来说,做所有这些都是一件很繁重的工作


你真的确定你需要这种行为吗?如果您更详细地解释您实际要完成的任务,您可能会得到更好的答案。

您的表单/控件应该具有
Invoke
方法。将回调委托传递给它,它应该在UI线程上执行它。哦,您应该能够在不创建新线程的情况下执行异步I/O之类的操作,只需使用异步API进行下载。您的代码中有什么不起作用?此应用程序没有“UI线程”。如果它没有GUI,那么您希望通过在主线程中调用委托来实现什么?感谢您提供的信息。。。我正在做的是创建一个抽象层。这些功能可以由GUI应用程序、命令行应用程序等使用。我希望API的用户能够调用异步函数,并向其传递回调。非常类似于如何在SQL Server和Http请求中使用AsyncCallback/IAsyncResult。我在网上找不到关于如何执行自己的AsyncCallback/IAsyncResult的太多信息。我不知道SQL Server的具体情况,但IAsyncResult通常不会执行任何特殊的wrt调用原始线程上的委托的操作。这些回调通常在用于完成操作的任何工作线程上调用。我不知道CF支持什么,但在.NET 4.5之前(异步/等待),您可以直接使用SynchronizationContext或BackgroundWorker(使用SynchronizationContext)来抽象这类内容。重要的是(GUI程序),委托将在正确的线程上调用,否则它将只在当前线程上调用。