在C#dll

时间:2015-09-18 12:45:41

标签: c# multithreading dll

我第一次使用C#DLL工作。 DLL方法将由C#应用程序调用。 UI将位于C#应用程序中。到目前为止,它非常基础。

但DLL中的工作必须在属于DLL的线程中完成。 DLL中的工作无法在UI线程上下文中执行。所以DLL方法调用将是异步的,这很好。

所以基本上这个想法是:

  • 应用程序在其项目中包含DLL。
  • DLL定义了各种代理。
  • 申请"订阅"这些代表。
  • UI线程调用DLL方法。
  • DLL接收方法调用。
  • 有一个上下文切换到DLL线程(实际上做与方法调用相关的工作)。
  • UI线程继续执行。 UI线程未被阻止,也不会等待。
  • DLL线程可以正常工作。
  • DLL线程调用委托来通知UI线程结果。

UI线程应该如何将消息发布到DLL线程?有这么简单的方法吗?

DLL线程调用委托时会发生什么?委托代码是在DLL线程上下文中还是在UI线程上下文中执行的?

似乎代码将在DLL线程上下文中执行。如果是这种情况,如何在UI线程上下文中执行委托代码?

感谢您的帮助!

==================

编辑:只要应用程序处于活动状态,DDL线程就必须保持活动状态。 DLL线程还将从网络接收事件,然后通知UI线程。

实际上,DLL需要是一个SDK才能进行VOIP调用。所以任何准备编写UI的人都可以使用我们的SDK。

典型(简化)方案是:

  • 在应用程序启动时,UI调用DLL.Start()。这将在DLL中创建一个线程,并确保DLL已准备好拨打和接听电话。

  • 用户拨打电话号码。

  • UI线程从DLL调用MakeCall()方法。

  • 在DLL中,有上下文切换到DLL线程以启动新调用。启动调用的所有工作都在DLL线程中完成。

  • UI线程未被阻止或不等待。

  • 此时,呼叫已建立。

  • DLL线程通过调用委托方法通知UI。

3 个答案:

答案 0 :(得分:1)

Task workerTask = Task.Factory.StartNew(() =>
{
    // call your dll and do some long process
});

Task uiTask = workerTask.ContinueWith((x) =>
{
    // update your ui (textBox.Text = x.Value;)
}, TaskScheduler.FromCurrentSynchronizationContext());

TaskScheduler.FromCurrentSynchronizationContext - 捕获当前(UI)同步上下文,因此将在ui上下文中进行更新

答案 1 :(得分:0)

  

应用程序是否需要有两个线程,一个线程   与DLL和UI的另一个线程进行通信?

您的应用程序只需要一个GUI线程和一个用于DLL上下文的附加线程。不需要进一步的线程来同步它们。

  

似乎代码将在DLL线程上下文中执行。如果   在这种情况下,如何在UI线程中执行委托代码   上下文

如果您尝试从创建其相应对象的GUI线程之外的另一个线程调用WinForm方法,则会获得InvalidOperationException,因为WinForms会检查此案例。一个简单的方法是检查是否需要在事件处理程序中更改线程上下文,如下所示:

处理事件:

public event Action<string> OnCallWithString;

事件处理程序:

void Form_OnCallWithString(string obj)
{
    if (InvokeRequired) Invoke(new Action<string>(Form_OnCallWithString), obj);
    else
    { 
        //normal eventhandler logic here
    }
}

答案 2 :(得分:-1)

您应该在C#中查找BackgroundWorker,这是为了完全按照您的意愿执行 - 在后台线程上执行某些操作并将结果传递回UI线程。

这比尝试在DLL中创建自己的线程和编组要好得多。让它只是一个函数库,让调用者担心它想要使用哪些线程。