【问题标题】:Is it possible to await Thread in C#是否可以在 C# 中等待线程
【发布时间】:2020-03-10 23:39:38
【问题描述】:

我必须手动生成一个新线程,所以我可以调用.SetApartmentState(ApartmentState.STA)。这意味着(据我所知)我不能使用Task。但我想知道线程何时完成运行,例如与async 一起使用的await。但是,我能想到的最好的方法是循环,不断检查Thread.IsAlive,如下所示:

var thread = new Thread(() =>
{ 
    // my code here 
});

thread.SetApartmentState(ApartmentState.STA);
thread.Start();

while(thread.IsAlive)
{
    // Wait 100 ms
    Thread.Sleep(100);
}

这应该可以工作(只要线程不会停止),但它似乎有点笨拙。难道没有更聪明的方法来检查线程何时完成(或死亡)吗?

这只是为了避免阻塞 GUI 线程,所以任何轻微的性能损失都可以(比如几百毫秒)。

【问题讨论】:

  • 您正在寻找一个非常奇怪的解决方案,相反,请解释您要解决的问题。
  • Thread.Join()?
  • 我要做的基本上是await Task.Run()。但由于 STA 限制,我不能这样做。我可以Thread.Join(),但同时不会阻塞 UI 线程吗?
  • 我忘记了示例中的 ApartmentState 部分。我现在已经添加了。我的错。
  • 这个问题能解决你的实际问题吗? stackoverflow.com/questions/16720496/…

标签: c# multithreading sta


【解决方案1】:

这是一个可用于启用线程等待的扩展方法(灵感来自这篇文章:await anything)。

public static TaskAwaiter GetAwaiter(this Thread thread)
{
    return Task.Run(async () =>
    {
        while (thread.IsAlive)
        {
            await Task.Delay(100).ConfigureAwait(false);
        }
    }).GetAwaiter();
}

使用示例:

var thread = new Thread(() =>
{ 
    Thread.Sleep(1000); // Simulate some background work
});
thread.IsBackground = true;
thread.Start();
await thread; // Wait asynchronously until the thread is completed
thread.Join(); // If you want to be extra sure that the thread has finished

【讨论】:

  • 真是个好主意。你认为在其中包含thread.SetApartmentState(ApartmentState.STA)thread.Start() 可能吗?所以它可以以类似于传统异步方法的方式运行...
  • GetAwaiter 方法只是为线程启用了await 运算符。可以像往常一样创建具有所需属性的线程。我用一个完整的例子更新了我的答案。
【解决方案2】:

你可以使用 BackgroundWorker 类吗?它有一个事件在完成时报告。

【讨论】:

  • 我试过了。 BackgroundWorker 类似乎在 MTA 中运行并且无法更改。
猜你喜欢
  • 2016-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多