linux 线程状态sta,为什么Task.Delay中断线程的STA状态?

介绍

这是一个冗长的问题!您将在开始时找到有关该问题的一些背景知识,然后是代码示例,这些示例已简化了表示形式,之后又简化了“问题”.请以任何适合您的顺序阅读!

背景资料

我正在为与STA COM通信的应用程序编写概念证明部分.应用程序的这一部分需要在单线程单元(STA)上下文中运行,以便与所述STA COM通信.该应用程序的其余部分在MTA上下文中运行.

当前状态

到目前为止,我想出的是创建一个包含在STA中运行的while循环的Communication类.需要中继到COM对象的工作通过ConcurrentQueue从外部排队到Communication类.然后,将工作项在while循环中出队并执行工作.

代码上下文

交流班

这是一个静态类,包含一个旨在在STA状态下运行的循环,并检查COM是否需要完成某些工作并将其分派到处理程序.

static class Communication

{

#region Public Events

/// This event is raised when the COM object has been initialized

public static event EventHandler OnCOMInitialized;

#endregion Public Events

#region Private Members

/// Stores a reference to the COM object

private static COMType s_comObject;

/// Used to queue work that needs to be done by the COM object

private static ConcurrentQueue s_workQueue;

#endregion Private Members

#region Private Methods

/// Initializes the COM object

private static void InternalInitializeCOM()

{

s_comObject = new COMType();

if (s_comObject.Init())

{

OnCOMInitialized?.Invoke(null, EventArgs.Empty);

}

}

/// Dispatches the work unit to the correct handler

private static void HandleWork(WorkUnit work)

{

switch (work.Command)

{

case WorkCommand.Initialize:

InternalInitializeCOM();

break;

default:

break;

}

}

#endregion Private Methods

#region Public Methods

/// Starts the processing loop

public static void StartCommunication()

{

s_workQueue = new ConcurrentQueue();

while (true)

{

if (s_workQueue.TryDequeue(out var workUnit))

{

HandleWork(workUnit);

}

// [Place for a delaying logic]

}

}

/// Wraps the work unit creation for the task of Initializing the COM

public static void InitializeCOM()

{

var workUnit = new WorkUnit(

command: WorkCommand.Initialize,

arguments: null

);

s_workQueue.Enqueue(workUnit);

}

#endregion Public Methods

}

工作指令

此类描述了需要完成的工作以及可能提供的任何参数.

enum WorkCommand

{

Initialize

}

工作单位

该枚举定义了COM可以执行的各种任务.

class WorkUnit

{

#region Public Properties

public WorkCommand Command { get; private set; }

public object[] Arguments { get; private set; }

#endregion Public Properties

#region Constructor

public WorkUnit(WorkCommand command, object[] arguments)

{

Command = command;

Arguments = arguments == null

? new object[0]

: arguments;

}

#endregion Constructor

}

所有者

这是拥有或产生与COM的通信的类的示例,并且是通信的抽象,供在应用程序的其余部分中使用.

class COMController

{

#region Public Events

/// This event is raised when the COM object has been initialized

public event EventHandler OnInitialize;

#endregion Public Events

#region Constructor

/// Creates a new COMController instance and starts the communication

public COMController()

{

var communicationThread = new Thread(() =>

{

Communication.StartCommunication();

});

communicationThread.SetApartmentState(ApartmentState.STA);

communicationThread.Start();

Communication.OnCOMInitialized += HandleCOMInitialized;

}

#endregion Constructor

#region Private Methods

/// Handles the initialized event raised from the Communication

private void HandleCOMInitialized()

{

OnInitialize?.Invoke(this, EventArgs.Emtpy);

}

#endregion Private Methods

#region Public Methods

/// Requests that the COM object be initialized

public void Initialize()

{

Communication.InitializeCOM();

}

#endregion Public Methods

}

问题

现在,看看Communication.StartCommunication()方法,更具体地讲这部分:

...

// [Place for a delaying logic]

...

如果用以下内容替换此行:

await Task.Delay(TimeSpan.FromMilliseconds(100)).ConfigureAwait(false);

// OR

await Task.Delay(TimeSpan.FromMilliseconds(100)).ConfigureAwait(true);

在检查过程中的最后一站-Communication.InternalInitializeCOM()线程所在的单元似乎是MTA.

但是,如果将延迟逻辑更改为

Thread.Sleep(100);

CommunicationInternalInitializeCOM()方法似乎在STA状态下执行.

该检查由Thread.CurrentThread.GetApartmentState()完成.

问题

谁能告诉我为什么Task.Delay破坏STA状态?还是我在做其他错误的事情?

谢谢!

感谢您抽出宝贵的时间阅读问题!祝你有美好的一天!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值