zoukankan      html  css  js  c++  java
  • 在非UI线程中自制Dispatcher

    在C#中,Task.Run当然是一个很好的启动新并行任务的机制,但是因为使用这个方法时,每次新的任务都会在一个新的线程中(其实就是线程池中的线程)运行

    这样会造成某些情形下现场调度的相对困难,即使我隔离出一个与UI无关的对象,然后用UI线程的Dispatcher实现对UI线程的交互,但是用Task启动的多个任务线程却难以管理,而且.net Core UWP已经不再提供具体线程调度的管理了

    最终我写了个这个玩意

        class NoUIDispatcher:IDisposable
        {
    #if DEBUG
            ~NoUIDispatcher()
            {
                System.Diagnostics.Debug.WriteLine(nameof(NoUIDispatcher) + " bedeleted");
            }
    #endif
            public async void Start()
            {
                await Task.Run(() =>
                {
                    try
                    {
                        normaltasklist = new List<Tuple<DispatchedHandler, OperationDeferral>>();
                        while (isdispose == false)
                        {
                            lock (normaltasklist)
                            {
                                if (normaltasklist.Count == 0)
                                {
                                    od.Start();
                                }
                                else
                                {
                                    normaltasklist[0].Item1.Invoke();
                                    normaltasklist[0].Item2?.Complete();
                                    normaltasklist.RemoveAt(0);
                                }
                            }
                            od.WaitOne();
                        }
                        normaltasklist = null;
                        System.Diagnostics.Debug.WriteLine(nameof(NoUIDispatcher) + " dispose");
                    }
                    catch
                    {
                        System.Diagnostics.Debug.WriteLine(nameof(NoUIDispatcher) + " error");
                    }
                });
            }
            OperationDeferral od = new OperationDeferral();
            List<Tuple<DispatchedHandler, OperationDeferral>> normaltasklist = null;
    
            public async Task RunAsync(DispatchedHandler agileCallback)
            {
                await Task.Run(() =>
                {
                    try
                    {
                        var pk = new OperationDeferral();
                        pk.Start();
                        /*if (normaltasklist == null)
                        {
                            System.Diagnostics.Debug.WriteLine(nameof(NoUIDispatcher) + " isdisposed");
                            return;
                        }*/
                        lock (normaltasklist)
                        {
                            normaltasklist.Add(new Tuple<DispatchedHandler, OperationDeferral>(agileCallback, pk));
                        }
                        od.CompleteWithoutDispose();
                        pk.WaitOne();
                    }
    #if DEBUG
                    catch (Exception e)
                    {
                        System.Diagnostics.Debug.WriteLine(nameof(NoUIDispatcher) + " " + e.ToString());
                    }
    #else
                    catch { }
    #endif
                });
            }
            public void Run(DispatchedHandler agileCallback)
            {
                Task.Run(() =>
                {
                    try
                    {
                        /*if (normaltasklist == null)
                        {
                            System.Diagnostics.Debug.WriteLine(nameof(NoUIDispatcher) + " isdisposed");
                            return;
                        }*/
                        lock (normaltasklist)
                        {
                            normaltasklist.Add(new Tuple<DispatchedHandler, OperationDeferral>(agileCallback, null));
                        }
                        od.CompleteWithoutDispose();
                    }
    #if DEBUG
                    catch (Exception e)
                    {
                        System.Diagnostics.Debug.WriteLine(nameof(NoUIDispatcher) + " " + e.ToString());
                    }
    #else
                    catch { }
    #endif
                }).IgnorCompletion();
            }
            bool isdispose = false;
            public void Dispose()
            {
                isdispose = true;
                od.Complete();
            }
        }
    
        public class OperationDeferral
        {
            System.Threading.AutoResetEvent are = new System.Threading.AutoResetEvent(false);
            public void Complete()
            {
                CompleteWithoutDispose();
                are.Dispose();
            }
            public void CompleteWithoutDispose()
            {
                are.Set();
            }
            public void Start()
            {
                are.Reset();
            }
            public Task WaitOneAsync()
            {
                return Task.Run(() =>
                {
                    try
                    {
                        are.WaitOne();
                    }
                    catch { }
                });
            }
            public void WaitOne()
            {
                are.WaitOne();
            }
        }
    
  • 相关阅读:
    MFC中实现LISTCRTL控件选中多行进行删除操作
    如何使属性值为“只读”(readonly)的EDIT控件在获取焦点后不显示光标?
    crm 使用stark组件
    ModelForm组件
    自定义admin管理工具(stark组件)
    Django-admin管理工具
    Django-session中间件源码简单分析
    基于角色的权限管理
    ajax参数补充
    datetime模块
  • 原文地址:https://www.cnblogs.com/yinyue200/p/6259535.html
Copyright © 2011-2022 走看看