精华内容
下载资源
问答
  • 最近在学习编写c#socket 多线程 异步处理客户端请求的一些东西。客户端发出请求,服务器端根据请求类型,调用不同的dll来进行异步的具体处理,这些都实现了。但是现在发现个问题,在比较多并发的情况下,调用dll处理...
  • 多线程调用MFC DLL、在MFC DLL创建多线程与线程安全. |' u f8 D8 G @# _( O & _! Y: J5 o' U9 d5 P. [+ \多线程调用: ! z: {1 ^9 c+ N g: ? S 1、动态库只有一个导出函数: $ w6 Y7 L/ S& `" | 这种情况...
    多线程调用MFC DLL、在MFC DLL创建多线程与线程安全. |' u  f8 D8 G  @# _( O

    & _! Y: J5 o' U9 d5 P. [+ \多线程调用: ! z: {1 ^9 c+ N  g: ?  S
    1、动态库只有一个导出函数: $ w6 Y7 L/ S& `" |
    这种情况非常少,也是最容易处理的情况。这种情况下编写函数时,只需要考虑不要有冲突的全局数据就可以了。这里的全局数据包括了在堆中分配的数据块和静态全局变量等。如果存在这样的全局数据,那么进程中的不同线程访问这个函数就会造成冲突。 & r3 s  |1 P/ `- v8 G" u
    解决办法也很简单,就是尽量用堆栈(stack)来解决问题。由于堆栈的所有人是线程,所以它必然是线程安全的。当然也要注意避免堆栈溢出。
    # c' O" o6 F' R2 t# D我们都知道,如果要在函数再次调用时保留前一次调用的状态,可以使用静态变量。但如果你要保持函数的线程安全,那么静态变量是不能用的,因为静态变量是全局的,是属于进程的,也就是属于进程内线程共享的。所以如果确实需要在同一线程中保持函数的状态,相当于在不同次调用间传递参数,可以考虑使用静态全局线程局部变量,即:
    ' H3 |2 W1 w0 M3 h* H/ l2 ?0 G__declspec( thread ) int tls_i = 1; , ?( X: `# i9 ~" M- a
    该变量定义就使编译器保证了tls_i是对应于每个线程的,即每个线程都一个tls_i的副本(copy),这样必然就是线程安全的。
    - K# w8 m! }$ {  R- e+ K" N2、动态库导出了多个函数,而且多个函数间存在数据传递。
    4 i! O6 F+ @, D就像前面说的,一般DLL都导出多个函数,一个初始化,一个资源释放,其他为核心功能函数。这些函数间极有可能发生数据传递。如果一个初始化函数是在线程A中调用的,而核心功能函数是在线程B中调用的,那么线程A初始化函数的资源就无法对应线程B中的核心功能,此外还有核心功能函数间的数据传递,这样的DLL就不是线程安全的,必然导致错误。
    5 S( H6 P$ v, H  ~: ]7 n解决办法是由用户(即使用DLL的人)保证这些导出函数是在一个线程中调用。但这样会很大程度上限制接口的设计和用户的使用自由度。所以最好的方法是函数只管自己的线程安全,不同函数传递数据用动态TLS,线程局部存储。
    ! I1 L7 _( \$ s) H6 Y2 W比如:
    5 f; {# E; X3 j我在全局定义了一个变量,用于存储当前线程局部存储的index ID。8 g+ e9 h+ ~7 Q) J/ q. |
    __declspec( thread ) int tls_i = 1; * c/ e! _" \1 e+ d4 Z$ h- ]
    当调用分配资源的函数时,调用动态TLS函数TlsAlloc,分配一个ID,将其记录在全局的线程安全的tls_i变量,并通过TlsSetValue函数将数据保存在线程安全的区域;当调用获取资源的函数时,通过TlsGetValue获取资源,处理完成后,调用Tlsfree对TLS index释放,以便新线程占有。 $ L" r0 f; w- S2 G) c* A% G( {; j
    这样,只要DLL中每个函数保证其局部是线程安全的,函数间传递数据通过TLS(静态和动态),就可以实现整个DLL的线程安全。 - _, ^( P) f2 z" @5 y
    3、限制访问DLL中某一函数的线程数目。 & O8 P3 N0 t% Q
    有时候,对于DLL中的某一个函数的访问线程数目是有限制的,超过了限制其他线程就得等一定的时间,一定的时间过后如果还不能得到执行机会,那就返回超时。这样的设计对用户来说是友好的,而且很实用,有的商业程序确实是按照允许用户访问的通道数目来计价的。 8 s4 @" Q/ G+ M5 ^7 ]( m
    对DLL中的函数做这样的一个封装,一般是简单的待用Semaphore信号量,来解决。DLL初始化时调用CreateSemaphore函数对信号量进行初始化,其原型如下:1 G( D" C5 [4 B8 I. ]
    HANDLE CreateSemaphore( 1 x8 K1 f/ P$ y3 L1 g$ I) P7 I
      LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
    , d( Y- _( T, l5 B- m" }" a                       // pointer to security attributes
    $ |/ F0 z$ @% P) W# ~" W6 L  LONG lInitialCount,  // initial count
    . i, e( B4 K3 e, O$ V& d# ?: l, j5 l& P  LONG lMaximumCount,  // maximum count
    & U  O& \8 \( i/ M  LPCTSTR lpName       // pointer to semaphore-object name   R; p# |. ^: s
    ); 2 ?# y$ A5 C" a4 p* _& Y6 j# K
    对于信号量,它每WaitForSingleObject一次(当然是要进入),其状态值(一个整数)就减1,使用完ReleaseSemaphore其状态值就加1,当其状态值为0时信号量就由有信号变为无信号。利用信号量的这一特性,我们在初始化时将信号量的初始值(第2个参数)设置为限制的线程访问数目。在要限制访问线程数目的函数内部,通过调用WaitForSingleOject获取控制权,并指定一个等待时间(这个由配置文件指定),根据情况超时返回,使用完ReleaseSemaphore释放对占用,让其他线程可以调用这个函数。 7 x5 ]$ Y% e/ n5 l7 O
    4、多进程情况下的多线程安全DLL。
    . t5 Z6 y" {3 x7 d6 o前面3讲了有时候需要对某一函数的访问线程进行限制,而我们知道,DLL是可以被多个进行加载并调用的。那就是说如果我们只对一个进程进行了限制,那么在多进程调用的情况下,这样的限制被轻易攻破。 7 q" B6 T: U# ~
    我们都知道,Semaphore信号量属于内核对象,也就是说其可以被多进程共享访问,也就说,如果我们给一个Semaphore指定了一个名字,在另一个进程中,我们只要调用OpenSemaphore函数用同一名字打开信号量就可以访问了。这样问题就解决了?   }: [6 O8 ~# S% W3 J+ S& {: q
    现实情况是,多进程情况下,一般不是简单的多进程共享一个Semaphore就可以了。多进程间需要互通很多信息。一般的解决办法是,采用共享数据段。
    ! c3 m9 R7 e0 R7 r# X/ ?#pragma data_seg("share") 0 s+ Q6 P9 t9 a$ C
    int share_data;
    & H6 H" f3 |% E5 O#pragma data_seg()
    $ P/ x1 y3 `  D( o) {#pragma comment(linker,"/SECTION:share, RWS")
    . C( y2 I4 d# [# u, ~通过pragam编译器指令生成了一个名叫share的共享数据段,这样对于变量share_data就可以多进程共享的了。如果要多进程间交换数据,只要在data_seg中添加数据定义即可。
    * ~2 H7 P* A- Y在MFC DLL中创建多线程: 5 B5 M$ }$ W. T, O' c
    除了在初始化过程中,只要MFC DLL 使用 TlsAlloc 这样的 Win32 线程本地存储区 (TLS) 函数来分配线程本地存储区,就可以安全地创建多线程。但是,如果 MFC DLL 是使用 __declspec(thread) 分配线程本地存储区,客户端应用程序必须隐式链接到 DLL。如果客户端应用程序显式链接到 DLL,对 LoadLibrary 的调用将不会成功加载此 DLL。 ! j8 v: ]9 M' O- U  `( o
    原因可以参考微软的这篇文章“PRB: Calling LoadLibrary() to Load a DLL That Has Static TLS”,地址:http://support.microsoft.com/kb/118816/en-us
    " l  e. z& M: e) c启动期间创建新的 MFC 线程的 MFC DLL 在由应用程序加载时将挂起。每当在下列对象内部通过调用 AfxBeginThreadCWinThread::CreateThread 创建线程时,就会发生这种情况: % ?8 G2 P6 ~" }; _, H
    9 `1 [* N6 W, H7 S2 p+ b. |/ H
    规则 DLL 中 CWinApp 派生对象的 InitInstance # H" N0 Y* I; c. Q/ h! w
    6 \: Y! o" z" K" ]8 k8 R) h% B
    规则 DLL 中提供的 DllMainRawDllMain 函数。 & y% I- @& V2 K$ G% m8 `1 h! t
    * E7 m% a- [6 r5 t2 u6 \$ c+ h. ?
    扩展 DLL 中提供的 DllMainRawDllMain 函数。& k9 b" Z$ }8 S' F0 R/ X
    为什么呢,原因可参考这篇文章“PRB: Cannot Create an MFC Thread During DLL Startup”,http://support.microsoft.com/kb/142243/en-us
    5 I! ~) z% Z4 F( [1 L3 e4 A) g解决办法:Regular DLLs that create threads should only do so in functions exported from the DLL and called by client applications.The recommended solution for MFC DLLs that need to create a thread when the DLL starts is to add a specific exported initialization function and create the thread in it.(创建多线程的规则dll,只能将启动线程的函数放入导出函数中,由客户端调用执行,不能在dll启动期间自动创建线程。)
    展开全文
  • dll中有一个读串口的函数; 我在C#两个线程中均会调用这个串口函数,运行时有冲突; 这是因为调用一个函数的原因?还是调用了一个串口的原因?还是两者都有?该怎么解决呢?求大佬们帮忙
  • 在C#中使用单线程调用DLL非常正常。 为达到充分利用网络资源的目的,[color=#FF0000]用C#在个线程中异步调用该DLL[/color],[color=#FF0000]却出现地址冲突等问题(DLL中的地址冲突)[/color]。 尝试在C#...
  • 多线程调用 opencv 图像处理

    千次阅读 2019-06-06 11:56:26
    调用相机视频进行实时处理,原本是基于c++ 的线程池实现的,后来编译成 dll,转用 c# 的线程池实现,Dll 里面的图像的处理过程还是比较的,但是经常会出现 dll 中内存地址访问冲突,通常是程序跑了一段时间之后。...

    背景

    调用相机视频进行实时处理,原本是基于c++ 的线程池实现的,后来编译成 dll,转用 c# 的线程池实现,Dll 里面的图像的处理过程还是比较多的,但是经常会出现 dll 中内存地址访问冲突,通常是程序跑了一段时间之后。

    通过 dll 的 debug,主要报错在图像的 resize/copyTo/clone 函数中,注释掉就没有报错了。

    定位问题

    先看下 copyTo 的实现

    void GpuMat::copyTo(OutputArray dst, InputArray mask) const
    {
        copyTo(dst, mask, Stream::Null());
    }
    

    这个直接用vs 跳转的,是 gpu 版本的定义;调用了以下第一个实现,注释中显示是non-blocking call,非阻塞的;不确定这里是不是线程安全的,通过 debug 定位到的问题就是,偶然会访问 image 的 data 出现访问冲突,读取字符出错…

    搜索了很多关于 opencv 线程安全的处理方式,有建议用 UMat 的矩阵定义方式,但是更改起来太复杂;而且实现也不完全是跟 Mat 等价的。

    最后发现似乎所有的情况都是跟访问 其中一个 Mat 有关,而这个 Mat 是根据 c# 传进来的图转化的,内存可能是跟 c# 是共享的,所以有时候会出错,在函数的入口直接 clone 一份,后面就没有复现这个问题。具体的原因还没完全定位到。

    //! copies those GpuMat elements to "m" that are marked with non-zero mask elements (Non-Blocking call)
    void copyTo(OutputArray dst, InputArray mask, Stream& stream) const;
    
    //! copies those GpuMat elements to "m" that are marked with non-zero mask elements (Blocking call)    
    void copyTo(OutputArray dst, InputArray mask) const;   
    

    补充记录

    c# 传图像到 dll 之后,对图像进行修改,然后在 c# 中直接取该图像即是修改后的图像数据,因为要展示到 wpf 的image 组件中,image 组件的 source 必须是 BitmapImage 类型,网上有 Bitmap 转换到 BitmapImage 的方式,但是有一个取内存的操作,目前我使用了 Emgv 的图像处理,所以读进来的图是 Image<Bitmap, byte>格式,提供一个默认的 img.toJpegData() 的方法,用于获取图像的二进制数据;但是后来发现这个步骤耗时很高,本机测试200ms,这个太夸张了。

    改用网上的转换方式,将 Bitmap 转换成 byte[];速度为40ms+,至少已经好多了。

    // 类似这样
    Bitmap b = new Bitmap( "test.bmp "); 
    MemoryStream ms = new MemoryStream(); 
    b.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp); 
    
    展开全文
  • 而且这些DLL有时会被多个进程同时调用,这就牵扯到多进程的多线程调用DLL的问题。有点绕口,以下我根据我实践中遇到的问题,分四种情况分享一下我解决此类问题的经验: 1、动态库只有一个导出函数。 这种情况非常...

    DLL有个共同的特点就是都有一个初始化函数,一个资源释放函数,其他几个函数都是核心功能函数。而且这些DLL有时会被多个进程同时调用,这就牵扯到多进程的多线程调用DLL的问题。有点绕口,以下我根据我实践中遇到的问题,分四种情况分享一下我解决此类问题的经验:

    1、动态库只有一个导出函数。

    这种情况非常少,也是最容易处理的情况。这种情况下编写函数时,只需要考虑不要有冲突的全局数据就可以了。这里的全局数据包括了在堆中分配的数据块和静态全局变量等。如果存在这样的全局数据,那么进程中的不同线程访问这个函数就会造成冲突。

    解决办法也很简单,就是尽量用堆栈(stack)来解决问题。由于堆栈的所有人是线程,所以它必然是线程安全的。当然也要注意避免堆栈溢出。

    我们都知道,如果要在函数再次调用时保留前一次调用的状态,可以使用静态变量。但如果你要保持函数的线程安全,那么静态变量是不能用的,因为静态变 量是全局的,是属于进程的,也就是属于进程内线程共享的。所以如果确实需要在同一线程中保持函数的状态,相当于在不同次调用间传递参数,可以考虑使用静态 全局线程局部变量,即:
     __declspec( thread ) int tls_i = 1;
     该变量定义就使编译器保证了tls_i是对应于每个线程的,即每个线程都一个tls_i的副本(copy),这样必然就是线程安全的。

    2、动态库导出了多个函数,而且多个函数间存在数据传递。

    就像前面说的,一般DLL都导出多个函数,一个初始化,一个资源释放,其他为核心功能函数。这些函数间极有可能发生数据传递。如果一个初始化函数是 在线程A中调用的,而核心功能函数是在线程B中调用的,那么线程A初始化函数的资源就无法对应线程B中的核心功能,此外还有核心功能函数间的数据传递,这 样的DLL就不是线程安全的,必然导致错误。

    解决办法是由用户(即使用DLL的人)保证这些导出函数是在一个线程中调用。但这样会很大程度上限制接口的设计和用户的使用自由度。所以最好的方法是函数只管自己的线程安全,不同函数传递数据用动态TLS,线程局部存储。

    比如:
    我在全局定义了一个变量,用于存储当前线程局部存储的index ID。
    __declspec( thread ) int tls_i = 1;
    当 调用分配资源的函数时,调用动态TLS函数TlsAlloc,分配一个ID,将其记录在全局的线程安全的tls_i变量,并通过TlsSetValue函 数将数据保存在线程安全的区域;当调用获取资源的函数时,通过TlsGetValue获取资源,处理完成后,调用Tlsfree对TLS index释放,以便新线程占有。

    这样,只要DLL中每个函数保证其局部是线程安全的,函数间传递数据通过TLS(静态和动态),就可以实现整个DLL的线程安全。

    3、限制访问DLL中某一函数的线程数目。

    有时候,对于DLL中的某一个函数的访问线程数目是有限制的,超过了限制其他线程就得等一定的时间,一定的时间过后如果还不能得到执行机会,那就返回超时。这样的设计对用户来说是友好的,而且很实用,有的商业程序确实是按照允许用户访问的通道数目来计价的。

    对DLL中的函数做这样的一个封装,一般是简单的待用Semaphore信号量,来解决。DLL初始化时调用CreateSemaphore函数对信号量进行初始化,其原型如下:
    HANDLE CreateSemaphore(
      LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
                           // pointer to security attributes
      LONG lInitialCount,  // initial count
      LONG lMaximumCount,  // maximum count
      LPCTSTR lpName       // pointer to semaphore-object name
    );
    对 于信号量,它每WaitForSingleObject一次(当然是要进入),其状态值(一个整数)就减1,使用完ReleaseSemaphore其状 态值就加1,当其状态值为0时信号量就由有信号变为无信号。利用信号量的这一特性,我们在初始化时将信号量的初始值(第2个参数)设置为限制的线程访问数 目。在要限制访问线程数目的函数内部,通过调用WaitForSingleOject获取控制权,并指定一个等待时间(这个由配置文件指定),根据情况超 时返回,使用完ReleaseSemaphore释放对占用,让其他线程可以调用这个函数。

    4、多进程情况下的多线程安全DLL。

    前面3讲了有时候需要对某一函数的访问线程进行限制,而我们知道,DLL是可以被多个进行加载并调用的。那就是说如果我们只对一个进程进行了限制,那么在多进程调用的情况下,这样的限制被轻易攻破。

    我们都知道,Semaphore信号量属于内核对象,也就是说其可以被多进程共享访问,也就说,如果我们给一个Semaphore指定了一个名字,在另一个进程中,我们只要调用OpenSemaphore函数用同一名字打开信号量就可以访问了。这样问题就解决了?

    现实情况是,多进程情况下,一般不是简单的多进程共享一个Semaphore就可以了。多进程间需要互通很多信息。一般的解决办法是,采用共享数据段。
    #pragma data_seg("share")
    int share_data=0;//需要初始化,否则全局变量被放到BSS段中,从而导致共享失败
    #pragma data_seg()
    #pragma comment(linker,"/SECTION:share, RWS") //如果不加这句,只是单纯的说明他们是放到数据段中,还没有共享
    通过pragam编译器指令生成了一个名叫share的共享数据段,这样对于变量share_data就可以多进程共享的了。如果要多进程间交换数据,只要在data_seg中添加数据定义即可。

    转载于:https://www.cnblogs.com/duyy/p/3741829.html

    展开全文
  • 在您面临的问题是,您需要在调用导出的线程上初始化VB6运行时。这包括初始化COM单元(STA)。最简单的方法是从python代码创建VB6类的实例。在在导出函数中“手动”初始化VB6运行时要困难得,并且需要使用自定义类型...

    从vb6dll导出函数的最简单方法是使用vbAdvance add-in,现在它是免费软件。在

    您面临的问题是,您需要在调用导出的线程上初始化VB6运行时。这包括初始化COM单元(STA)。最简单的方法是从python代码创建VB6类的实例。在

    在导出函数中“手动”初始化VB6运行时要困难得多,并且需要使用自定义类型库来调用API函数(在初始化运行时之前不能使用声明或内置VB6函数)。在

    这是我正在使用的一个函数Private Function pvInitVbRuntime() As Boolean

    ' Const FUNC_NAME As String = "pvInitVbRuntime" '

    Const PROGID_DUMMY As String = LIB_NAME & ".cDummy"

    Dim lIdx As Long

    lIdx = GetModuleHandle("MSVBVM60.DLL")

    lIdx = GetProcAddress(lIdx, "__vbaSetSystemError")

    Call RtlMoveMemory(lIdx, ByVal lIdx + 9, 4)

    Call RtlMoveMemory(lIdx, ByVal lIdx, 4)

    If TlsGetValue(lIdx) <> 0 Then

    Call CoCreateInstance(CLSIDFromProgID(PROGID_DUMMY), Nothing, CLSCTX_INPROC_SERVER, VBGUIDFromString("{00000000-0000-0000-C000-000000000046}"), Nothing)

    pvInitVbRuntime = True

    Else

    ' Call APIOutputDebugString(GetCurrentThreadId() & ": not a VB thread [" & LIB_NAME & "." & MODULE_NAME & "." & FUNC_NAME & "]" & vbCrLf) '

    End If

    End Function

    所有API函数(GetModuleHandle,GetProcAddress,RtlMoveMemory,TlsGetValue,CoCreateInstance,CLSIDFromProgID,VBGUIDFromString,APIOutputDebugString)都在自定义类型库中声明。基本上,它在线程上创建一个虚拟的VB6类(称为cDummy)。如果单元尚未初始化(未调用CoInitialize),则函数将失败。在

    展开全文
  • 换成IE7后没有安全问题了,可以运行,但是提示内存访问冲突,断点在调用外部DLL时: 我的源代码如下: // DTUTest.h : CDTUTest 的声明 #pragma once #include "resource.h" // 主符号 #include "windows.h" #include ...
  • libcmt.lib是windows环境下vc提供的静态运行时库(多线程);msvcrt.lib是动态运行时库。 原因 由于DLL(或EXE)工程设置的Runtime Library 和 它导入的其他(.lib)库的Runtime Library不同。 比如: 下面为Release...
  • 什么是C运行时库 每一个程序都会调用标准库的函数,最终都要拷贝一份标准库的实现到程序中,这样同一时刻内存中可能有许多份标准库的代码。...C运行时库诞生于20世纪70年代,当时的程序是单线程的,任务或线...
  • 若该参数NULL,传递给调用线程的WM_HOTKEY消息必须在消息循环中中进行处理。 id:定义热键的标识符。调用线程中的其他热键不能使用同样的标识符。应用功能程序必须定义一个0X0000-0xBFFF范围的值。一个共享的动态...
  • 编程高手箴言(推荐)

    2014-12-23 11:39:34
    7.3 多线程应用的调试 350 7.4 非固定错误的调试 352 7.4.1 激活调试环境 352 7.4.2 正确区分错误的类型 356 7.4.3 常见的偶然错误 357 第8章 内核优化 358 8.1 数据类型的认识 358 8.2 X86优化编码准则 359 8.2.1 ...
  • Python Cookbook

    2013-07-31 22:33:26
    17.5 在多线程环境中使用SWIG生成的模块 603 17.6 用PySequence_Fast将Python序列转为 C数组 604 17.7 用迭代器逐个访问Python序列的元素 608 17.8 从Python可调用的C函数中返回None 611 17.9 用gdb调试动态载入...
  • 3、**还有就是读数据库不用多线程读了,在等待数据返回的期间不会卡客户端,另外自己用多线程会引发冲突 4、**修复客户端退出后,在登录用户服务端崩溃问题。 [2020-2-23] ================ 1、**数据库读取增加...
  • xscan

    热门讨论 2011-11-04 17:50:27
    采用多线程方式对指定IP地址段(或单机)进行安全漏洞检测,支持插件功能,提供了图形界面和命令行两种操作方式,扫描内容包括:远程服务类型、操作系统类型及版本,各种弱口令漏洞、后门、应用服务漏洞、网络设备...
  • 处理器的线程调度算法 366 6.6 作业对象 369 6.7 本章总结 374 第7章 内存管理 375 7.1 内存管理器简介 375 内存管理器组件 376 内部同步 377 配置内存管理器 378 检查内存的使用情况 378 7.2 内存管理器提供的...
  • 1) 修改在静态编译的DLL调用其它DLL失败的BUG 2) 修改静态编译后“选择列表框”在“单选”属性为真时不显示项目内容的BUG 3) 修改核心库中“播放音乐”命令在没有声卡或声卡被禁用时未正确释放资源的BUG 4) ...
  •  0288 试图释放不属于调用者的路同步信号。  0298 信号投递的次数太。  0299 仅完成部分 ReadProcessMemory 或 WriteProcessMemory 请求。  0300 操作锁定请求被拒绝。  0301 系统接收了一个无效的...
  • 本书分10章,共有1000个实例,编写时从产生电脑故障的各个方面入手,涉及到硬件、软件等各方面的内容,其中包括开/关机中的问题、操作中的问题、软件运用的故障、外设故障以及病毒防治等等,这些都是个人电脑使用...
  • C#微软培训教材(高清PDF)

    千次下载 热门讨论 2009-07-30 08:51:17
    18.2 在 C #代码中调用 C++和 VB 编写的组件 .240 18.3 版 本 控 制 .249 18.4 代 码 优 化 .252 18.5 小 结 .254 第五部分 附 录 .255 附录 A 关 键 字.255 附录 B 错 误 码.256 附录 C .Net 名字空间...
  • C#微软培训资料

    2014-01-22 14:10:17
    18.2 在 C #代码中调用 C++和 VB 编写的组件 .240 18.3 版 本 控 制 .249 18.4 代 码 优 化 .252 18.5 小 结 .254 第五部分 附 录 .255 附录 A 关 键 字.255 附录 B 错 误 码.256 附录 C .Net 名字空间...
  • asp.net知识库

    2015-06-18 08:45:45
    ASP.NET 2.0中小心Profile命名冲突 使用ASP.NET 2.0 Profile存储用户信息[翻译] Level 200 [ASP.NET 2.0]PageParser.GetCompiledPageInstance中存在一个Bug 如何在DotNet 2的登录组件中检索用户的锁定状态及解锁? ...
  • 但是,使用同步方法比调用其异步变体容易得。这在C# 5.0版本中有了改变。异步编程与编写同步程序一样容易。新的C#关键字基于自从.NET 4.0以来就有的.NET并行库,现在该语言提供了高效功能。 Windows Store应用...

空空如也

空空如也

1 2
收藏数 25
精华内容 10
关键字:

多线程调用dll冲突