日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

C#的ApartmentState的属性:[STAThread]

發布時間:2024/9/20 C# 65 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C#的ApartmentState的属性:[STAThread] 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

每個Thread都有一個關于ApartmentState的屬性,可以把它設置為:STA或者MTA,或者UNKNOWN。
當你想指定工程的啟動窗口的時候,你需要在該窗口類中申明一個Main()方法,并為這個方法設置[STAThread]屬性。

[STAThread]是Single Thread Apartment單線程套間的意思,是一種線程模型,用在程序的入口方法上
(在C#和VB.NET里是Main()方法),來指定當前線程的ApartmentState 是STA。用在其他方法上不產生影響。
在aspx頁面上可以使用AspCompat = "true" 來達到同樣的效果。這個屬性只在 Com Interop 有用,
如果全部是 managed code 則無用。簡單的說法:[STAThread]指示應用程序的默認線程模型是單線程單元 (STA)。
啟動線程模型可設置為單線程單元或多線程單元。如果未對其進行設置,則該線程不被初始化。也就是說如果你用的.NET Framework,
并且沒有使用COM Interop,一般不需要這個Attribute。其它的還有MTA(多線程套間)、Free Thread(自由線程)。
單線程套間,簡單來說所有對于單線程套間中對象的訪問都是通過消息來傳遞的,所以同一時間只有一個線程能夠訪問單線程套間中的對象。
例如:
class?MainClass

{?[STAThread]static?void?Main(string[] args){?Teacher teacher?=?new?Teacher();?Student student?=?new?Student();?student.AdviseDelegateInstance?=?new?Student.AdviseDelegate(teacher.Advise);?Console.WriteLine("Student got 49");?student.SetScore(49);?Console.WriteLine("Student got 87");?student.SetScore(87);?Console.ReadLine();?}?}
表示這個Main程序被一個單線程套間包住,且Main的執行,一次只能被一個線程占用,這個線程未執行完,別的線程是沒辦法調用的。

http://blog.csdn.net/qilang/archive/2006/06/06/775605.aspx

STA不是單線程的意思.英文為single threaded apartment.是一種套間(或譯為公寓)線程模式.

sta thread并不表明應用程式的類型,和應用程序不搭界,恰相反,一個應用程序可以有多個線程.每個線程也可以有多個組件或對象.以前win16位系統的組件線程模式才真正是單線程.這是一種被淘汰了的模式.
線程模式用于處理組件在多線程的環境里并行與并互的方式.比如套間線程(STAThread)模式中接口跨線程傳遞必須被調度(Marshal),不調度直傳肯定會失敗!而MTA或FreeThread模式中的接口可以不經調度直接傳遞.
這種調度在特定的環境中非常影響性能(可有幾百倍之差).如VB里只支持STAThread模式.FreeThread模式的組件會在里面表現成和跨進程一樣慢!
線程模式是微軟的COM基礎中的極其重要的概念.一定要吃透!
我對.net真是一竅不通(沒空去弄,對不起微軟去年的獎賞).但我可以肯定,C#中的[STAThread]屬性是應用程序的套間初始化代碼.可以直接理解成SDK里的
CoInitialize(NULL);
初始一個STA套間實際上是相當于開了一個消息窗口,所有調用經此窗口過程調度到組件內.
同理[MTAThread](不知有沒有這個屬性,自已去查)
可以理解成
CoInitializeEx(NULL,COINIT_MULTITHREADED )
這經常是一個對初入com大門的人來說,有一定難度但必須過的一道關.

打開一個其他人寫的C#程序,為了下面的講解,我把這個程序叫作”DeltaEngine”。DeltaEngine會調用一個本地的程序集,并處理其中某些事件。然后建一個工程,把DeltaEngine作為庫項目引用,這個工程又被一個VB程序引用。我把這個VB程序叫做"VBApp"。所以,引用結構就像:

VBApp (VB) -> DeltaEngine (C#) -> NativeCode

當我把VBApp作為啟動程序運行時,它會一直等待NativeCode里面的事件在DeltaEngine中被處理。我注意到,如果我把DeltaEngine作為啟動程序來運行的話,事件就會像預期那樣得到處理。我花了很多時間想解決這個問題,但還是很困惑。

最后有人指出,VB項目的默認線程模型是單線程套間(SingleThreaded?Apartment),而C#項目的默認線程模型是多線程套間 (Multithreaded Apartment)。因為DeltaEngine最初是作為C#工程開發的,被默認為使用MTA。當使用VBApp作為啟動程序調用DeltaEngine時,DeltaEngine就會使用STA。因為這樣,DeltaEngine就會開始等待其實它已經喚起的事件,所以DeltaEngine會一直等待下去。如果我把DeltaEngine作為啟動程序運行,它就會使用MTA并且會像預期那樣工作。

解決的方法就是把MTAThreadAttribute加進VBApp的主函數里面。如下:

<MTAThread> Sub Main()

類似,如果你想把STAThread attribute加進C#的主方法里面,如下:

[STAThread]

static void Main()

WindowsForms程序要求使用STA,所以創建C# Winapp后,你可以在Program.cs看見像這樣的代碼。

我就不重復一些已經有的關于STATread 和MTAThread的文件,所以我給出下面的一些link可以學到更多關于STATread 和MTAThread的東西。

C# 中WindowsForm 的初始化信息 [STAThread]
static class Program

{

/// <summary>

/// The main entry point for the application.

/// </summary>

[STAThread]

static void Main()

{

Application.EnableVisualStyles();

Application.SetCompatibleTextRenderingDefault(false);

Application.Run(new Form1());

}

}

以上的代碼是VS 2005中默認的初始化信息.

Application.EnableVisualStyles();

簡單的說就是讓你的控件顯示出來.當然是在WindowsForm 中

此方法為應用程序啟用可視樣式。如果控件和操作系統支持視覺樣式,則控件將以視覺樣式進行繪制。若要使 EnableVisualStyles 生效,必須在應用程序中創建任何控件之前調用它;EnableVisualStyles 通常是 Main 函數的第一行.

下面的代碼示例演示如何在 Main 函數中調用 EnableVisualStyles 來啟用應用程序的視覺樣式

對于支持?FlatStyle?屬性的控件,請確保將?FlatStyle?屬性設置為?FlatStyle.System?值。


using System;

using System.Drawing;

using System.Windows.Forms;

namespace VStyles

{

public class Form1 : System.Windows.Forms.Form

{

private System.Windows.Forms.Button button1;

[STAThread]

static void Main()

{

Application.EnableVisualStyles();

Application.Run(new Form1());

}

public Form1()

{

this.button1 = new System.Windows.Forms.Button();

this.button1.Location = new System.Drawing.Point(24, 16);

this.button1.Size = new System.Drawing.Size(120, 100);

this.button1.FlatStyle = FlatStyle.System;

this.button1.Text = "I am themed.";

// Sets up how the form should be displayed and adds the controls to the form.

this.ClientSize = new System.Drawing.Size(300, 286);

this.Controls.Add(this.button1);

this.Text = "Application.EnableVisualStyles Example";

}

}

}

由于很多COM在.NET環境下如果使用多線程的話,會導致引用的COM不能正常運行,而如果不聲明程序為STAThread的話,.NET就會自動使用多線程來提高效率,這樣就會導致不可預知的后果。

總結

以上是生活随笔為你收集整理的C#的ApartmentState的属性:[STAThread]的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。