C# 如何确保在单个线程中执行可等待的操作
C# How can I make sure to execute awaitable operations in a single thread
我正在构建一个 UWP 应用程序,其中显然包含对异步方法的多个等待调用。
在其中一个事件处理程序中,我需要确保调用链是在单个线程中执行的。
我试图通过等待并获取结果来制作我需要的 "sync" 版本的异步方法,如下所示:
public static T Sync<T>(this Task<T> task)
{
if (task == null)
return default(T);
return task.ConfigureAwait(false).GetAwaiter().GetResult();
}
或者更残酷:
public static T Sync<T>(this Task<T> task)
{
if (task == null)
return default(T);
task.Wait();
return task.Result;
}
但是我遇到了其他几个博客中描述的死锁问题,因为我 运行 在 UI 线程上。
有什么方法可以实现我的目标吗?
如果您只关心序列化对状态的访问(即您一次只希望一个线程修改状态),您可以使用 .NET 中内置的众多同步原语之一来实现这一点。
最简单的工具之一是 lock
语句。
当然这会产生阻塞您的 Task
的副作用,这可能不适合您的应用程序。但是 "async" locks.
有一些可用的实现
How can I make sure to execute awaitable operations in a single thread
正如其他人指出的那样,默认情况下 UI 线程上的 async
/await
将 在单个线程上执行所有延续。
I want to avoid that while I am awaiting, another async call changes my state.
正确的解决方案是修正你的逻辑。任何替代方案 - 特别是使 UI 线程无响应 - 都会降低您的用户体验,并可能阻止您的应用程序在商店中被接受。
就是说,如果您绝对确定您想沿着这条路走下去而不是首先修复您的代码,您有两个主要选择:
- 使所有代码同步。它会 运行 在 UI 线程上并根据需要阻止它。
- 运行 一个嵌套的消息循环。我不确定 UWP 是否支持此功能;你 可能 可以使用我的
AsyncContext
. 让一些东西工作
同样,这两种 这些解决方案都会使您的 UI 无响应,降低您的用户体验并可能导致商店拒绝。
我正在构建一个 UWP 应用程序,其中显然包含对异步方法的多个等待调用。
在其中一个事件处理程序中,我需要确保调用链是在单个线程中执行的。
我试图通过等待并获取结果来制作我需要的 "sync" 版本的异步方法,如下所示:
public static T Sync<T>(this Task<T> task)
{
if (task == null)
return default(T);
return task.ConfigureAwait(false).GetAwaiter().GetResult();
}
或者更残酷:
public static T Sync<T>(this Task<T> task)
{
if (task == null)
return default(T);
task.Wait();
return task.Result;
}
但是我遇到了其他几个博客中描述的死锁问题,因为我 运行 在 UI 线程上。
有什么方法可以实现我的目标吗?
如果您只关心序列化对状态的访问(即您一次只希望一个线程修改状态),您可以使用 .NET 中内置的众多同步原语之一来实现这一点。
最简单的工具之一是 lock
语句。
当然这会产生阻塞您的 Task
的副作用,这可能不适合您的应用程序。但是 "async" locks.
How can I make sure to execute awaitable operations in a single thread
正如其他人指出的那样,默认情况下 UI 线程上的 async
/await
将 在单个线程上执行所有延续。
I want to avoid that while I am awaiting, another async call changes my state.
正确的解决方案是修正你的逻辑。任何替代方案 - 特别是使 UI 线程无响应 - 都会降低您的用户体验,并可能阻止您的应用程序在商店中被接受。
就是说,如果您绝对确定您想沿着这条路走下去而不是首先修复您的代码,您有两个主要选择:
- 使所有代码同步。它会 运行 在 UI 线程上并根据需要阻止它。
- 运行 一个嵌套的消息循环。我不确定 UWP 是否支持此功能;你 可能 可以使用我的
AsyncContext
. 让一些东西工作
同样,这两种 这些解决方案都会使您的 UI 无响应,降低您的用户体验并可能导致商店拒绝。