gpt4 book ai didi

c# - 在无法设置当前单元模型的单线程单元中运行代码并返回值

转载 作者:太空宇宙 更新时间:2023-11-03 10:25:03 24 4
gpt4 key购买 nike

我有一个调用需要在单线程上下文中进行,但我不能通过设置 [STAThread] 来保证这一点。在我的代码中,因为我不控制入口点,我的代码将通过反射调用。

我想出了这种调用并返回 token 的方法,但我希望有更好的方法:

private static string token;

private static Task<string> GetToken(string authority, string resource, string scope) // I don't control this signature, as it gets passed as a delegate
{
Thread t = new Thread(GetAuthToken);

t.SetApartmentState(ApartmentState.STA);
t.Start();
t.Join();

return Task.Run(() =>
{
return token;
});
}

private static void GetAuthToken()
{
Credentials creds = AuthManagement.CreateCredentials(args); // this call must be STA
token = creds.Token;
}

我的约束:

  • 第一个方法的签名必须Task<string> MyMethod(string, string, string)
  • AuthManagement.CreateCredentials(args) 必须在单线程单元上下文中调用
  • 当前线程上下文不能保证是 STA,因此应该假设是 MTA。

我需要以保证是 STA 的方式调用该方法,并返回结果。

感谢您的帮助!

最佳答案

有一个稍微好一点的方法。您将必须创建一个新线程以保证您在 STA 线程上,因为在线程启动后您无法更改线程的单元状态。但是,您可以摆脱 Thread.Join() 调用,这样您的方法实际上是异步的,使用 TaskCompletionSource :

private static async Task<string> GetToken(string authority, string resource, string scope) // I don't control this signature, as it gets passed as a delegate
{
using (var tcs = new TaskCompletionSource<string>()) {
Thread t = new Thread(() => GetAuthToken(tcs));
t.SetApartmentState(ApartmentState.STA);
t.Start();
var token = await tcs.Task
return token;
}
}

private static void GetAuthToken(TaskCompletionSource<string> tcs)
{
try {
Credentials creds = AuthManagement.CreateCredentials(args); // this call must be STA
tcs.SetResult(creds.Token);
}
catch(Exception ex) {
tcs.SetException(ex);
}
}

此外,如果您需要在任务中包装返回值,请使用 Task.FromResult() 而不是 Task.Run()

关于c# - 在无法设置当前单元模型的单线程单元中运行代码并返回值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31929459/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com