C# 多线程 05-使用 C#6.0 09-对动态类型使用 await
🏷️ 《C# 多线程》
实现的功能同 05-使用 C#6.0 08-自定义 awaitable 类型 是一样的,只是这里是使用动态类型实现的。
注意
本例需要导入 ImpromptuInterface
包
示例代码
csharp
using ImpromptuInterface;
using System;
using System.Dynamic;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
namespace Recipe5_9
{
class Program
{
/// <summary>
/// 对动态类型使用 await
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
Task t = AsynchronousProcessing();
t.Wait();
Console.ReadLine();
}
static async Task AsynchronousProcessing()
{
// 通过参数指定 IsCompleted 为 true,只需同步调用 GetResult 方法
string result = await GetDynamicAwaitableObject(true);
Console.WriteLine(result);
// 通过参数指定 IsCompleted 为 false,则会先执行 OnCompleted 方法
result = await GetDynamicAwaitableObject(false);
Console.WriteLine(result);
}
static dynamic GetDynamicAwaitableObject(bool completeSynchronously)
{
// ExpandoObject 类型可在运行时动态添加和删除其成员的对象
dynamic result = new ExpandoObject(); // 类型 t
dynamic awaiter = new ExpandoObject(); // 类型 A
awaiter.Message = "Completed synchronously";
awaiter.IsCompleted = completeSynchronously;
awaiter.GetResult = (Func<string>)(() => awaiter.Message);
awaiter.OnCompleted = (Action<Action>)(callback => ThreadPool.QueueUserWorkItem(state =>
{
Thread.Sleep(TimeSpan.FromSeconds(3));
awaiter.Message = GetInfo();
callback?.Invoke();
}));
// 使用 Impromptu.ActLike 方法动态的创建代理对象,该对象将实现任何需要的接口
IAwaiter<string> proxy = Impromptu.ActLike(awaiter);
// t 有一个名为 GetAwaiter 的可访问的实例或扩展方法
result.GetAwaiter = (Func<dynamic>)(() => proxy);
return result;
}
static string GetInfo()
{
return $"Task is running on a thread id {Thread.CurrentThread.ManagedThreadId}. Is thread pool thread: {Thread.CurrentThread.IsThreadPoolThread}";
}
}
public interface IAwaiter<T> : INotifyCompletion
{
bool IsCompleted { get; }
T GetResult();
}
}
运行结果
txt
Completed synchronously
Task is running on a thread id 3. Is thread pool thread: True