金沙国际官网_金沙国际平台登录

因为这个金沙国际官网_金沙国际平台登录网站与很多的大型澳门赌场都有合作,金沙国际官网_金沙国际平台登录尽职尽责,高效执行,保持好奇心,不断学习,追求卓越,点击进入金沙国际官网_金沙国际平台登录马上体验吧,所以现在也正式地开始了营业。

您的位置:金沙国际官网 > 编程 > 线程安全类型,谷歌瓦片地图纠偏

线程安全类型,谷歌瓦片地图纠偏

发布时间:2019-10-31 20:16编辑:编程浏览(163)

    1、值类型与引用类型区别

    1、IProducerConsumerCollection (线程安全接口)
      此接口的所有实现必须都启用此接口的所有成员,若要从多个线程同时使用。

        对谷歌瓦片地图进行纠偏,有两种方法:一是对拼接大图进行纠偏,然后重新切片;二是直接对瓦片图进行纠偏。这里我用的是第二种方法,即直接对瓦片地图进行纠偏。

      值类型 引用类型
    存储方式 直接存储值本身 存储数据的引用,数据存在数据堆上
    内存分配 分配在栈上  分配在堆上
    内存回收 用完直接回收  不会直接加收,通过GC机制回收
    实例分配 一般是存在栈上如果是类的属性也有可能随类存在堆上 一定分配在堆上
    效率   不需要地址转换效率高 需要进行地址转换效率低
    赋值操作 直接创建对象   创建对象的引用

    图片 1图片 2

    App.config配置:

     

    using System;
    using System.Collections;
    using System.Collections.Concurrent;
    using System.Collections.Generic;
    
    namespace ConsoleApp1
    {
        public class SafeStack<T> : IProducerConsumerCollection<T>
        {
            // Used for enforcing thread-safety
            private object m_lockObject = new object();
    
            // We'll use a regular old Stack for our core operations
            private Stack<T> m_sequentialStack = null;
    
            //
            // Constructors
            //
            public SafeStack()
            {
                m_sequentialStack = new Stack<T>();
            }
    
            public SafeStack(IEnumerable<T> collection)
            {
                m_sequentialStack = new Stack<T>(collection);
            }
    
            //
            // Safe Push/Pop support
            //
            public void Push(T item)
            {
                lock (m_lockObject) m_sequentialStack.Push(item);
            }
    
            public bool TryPop(out T item)
            {
                bool rval = true;
                lock (m_lockObject)
                {
                    if (m_sequentialStack.Count == 0) { item = default(T); rval = false; }
                    else item = m_sequentialStack.Pop();
                }
                return rval;
            }
    
            //
            // IProducerConsumerCollection(T) support
            //
            public bool TryTake(out T item)
            {
                return TryPop(out item);
            }
    
            public bool TryAdd(T item)
            {
                Push(item);
                return true; // Push doesn't fail
            }
    
            public T[] ToArray()
            {
                T[] rval = null;
                lock (m_lockObject) rval = m_sequentialStack.ToArray();
                return rval;
            }
    
            public void CopyTo(T[] array, int index)
            {
                lock (m_lockObject) m_sequentialStack.CopyTo(array, index);
            }
    
    
    
            //
            // Support for IEnumerable(T)
            //
            public IEnumerator<T> GetEnumerator()
            {
                // The performance here will be unfortunate for large stacks,
                // but thread-safety is effectively implemented.
                Stack<T> stackCopy = null;
                lock (m_lockObject) stackCopy = new Stack<T>(m_sequentialStack);
                return stackCopy.GetEnumerator();
            }
    
    
            //
            // Support for IEnumerable
            //
            IEnumerator IEnumerable.GetEnumerator()
            {
                return ((IEnumerable<T>)this).GetEnumerator();
            }
    
            // 
            // Support for ICollection
            //
            public bool IsSynchronized
            {
                get { return true; }
            }
    
            public object SyncRoot
            {
                get { return m_lockObject; }
            }
    
            public int Count
            {
                get { return m_sequentialStack.Count; }
            }
    
            public void CopyTo(Array array, int index)
            {
                lock (m_lockObject) ((ICollection)m_sequentialStack).CopyTo(array, index);
            }
        }
    }
    

    图片 3图片 4

    2、装箱拆箱

    SafeStack

    <appSettings>
      <add key="inputPath" value="D:_临时文件GISMap1818940751"/>
      <add key="outputPath" value="D:_临时文件GISMapOutput1818940751"/>
      <add key="deltaPixcelX" value="1031"/>
      <add key="deltaPixcelY" value="421"/>
      <add key="fromMapZoom" value="1"/>
      <add key="toMapZoom" value="18"/>
    </appSettings>
    

    装箱:值类型转换成引用类型。将值类型从栈上拷贝到堆上,将地址返回;

    图片 5图片 6

    View Code

    拆箱:引用类型转换成值类型。将引用类型的数据拷贝到栈上。

    using System;
    using System.Collections.Concurrent;
    
    namespace ConsoleApp1
    {
        class Program
        {
            static void Main()
            {
                TestSafeStack();
    
                // Keep the console window open in debug mode.
                Console.WriteLine("Press any key to exit.");
                Console.ReadKey();
            }
    
            // Test our implementation of IProducerConsumerCollection(T)
            // Demonstrates:
            //      IPCC(T).TryAdd()
            //      IPCC(T).TryTake()
            //      IPCC(T).CopyTo()
            static void TestSafeStack()
            {
                SafeStack<int> stack = new SafeStack<int>();
                IProducerConsumerCollection<int> ipcc = (IProducerConsumerCollection<int>)stack;
    
                // Test Push()/TryAdd()
                stack.Push(10); Console.WriteLine("Pushed 10");
                ipcc.TryAdd(20); Console.WriteLine("IPCC.TryAdded 20");
                stack.Push(15); Console.WriteLine("Pushed 15");
    
                int[] testArray = new int[3];
    
                // Try CopyTo() within boundaries
                try
                {
                    ipcc.CopyTo(testArray, 0);
                    Console.WriteLine("CopyTo() within boundaries worked, as expected");
                }
                catch (Exception e)
                {
                    Console.WriteLine("CopyTo() within boundaries unexpectedly threw an exception: {0}", e.Message);
                }
    
                // Try CopyTo() that overflows
                try
                {
                    ipcc.CopyTo(testArray, 1);
                    Console.WriteLine("CopyTo() with index overflow worked, and it SHOULD NOT HAVE");
                }
                catch (Exception e)
                {
                    Console.WriteLine("CopyTo() with index overflow threw an exception, as expected: {0}", e.Message);
                }
    
                // Test enumeration
                Console.Write("Enumeration (should be three items): ");
                foreach (int item in stack)
                    Console.Write("{0} ", item);
                Console.WriteLine("");
    
                // Test TryPop()
                int popped = 0;
                if (stack.TryPop(out popped))
                {
                    Console.WriteLine("Successfully popped {0}", popped);
                }
                else Console.WriteLine("FAILED to pop!!");
    
                // Test Count
                Console.WriteLine("stack count is {0}, should be 2", stack.Count);
    
                // Test TryTake()
                if (ipcc.TryTake(out popped))
                {
                    Console.WriteLine("Successfully IPCC-TryTaked {0}", popped);
                }
                else Console.WriteLine("FAILED to IPCC.TryTake!!");
            }
        }
    }
    

    对瓦片图进行纠偏处理的算法代码:

     3、JS遍历

    Program

    图片 7图片 8

    for语句:和c#一样

    2、ConcurrentStack类:安全堆栈

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Configuration;
    using System.Data;
    using System.Drawing;
    using System.IO;
    using System.Linq;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Threading;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using Utils;
    
    namespace TileProcess
    {
        public partial class Form1 : Form
        {
            private int _count = 0;
            private int _deltaPixcelX;
            private int _deltaPixcelY;
            private string _inputPath;
            private string _outputPath;
            private int _fromMapZoom;
            private int _toMapZoom;
    
            private DateTime _startTime;
            private int _lastCount;
    
            public Form1()
            {
                InitializeComponent();
    
                _deltaPixcelX = Convert.ToInt32(ConfigurationManager.AppSettings["deltaPixcelX"]);
                _deltaPixcelY = Convert.ToInt32(ConfigurationManager.AppSettings["deltaPixcelY"]);
                _inputPath = ConfigurationManager.AppSettings["inputPath"];
                _outputPath = ConfigurationManager.AppSettings["outputPath"];
                _fromMapZoom = Convert.ToInt32(ConfigurationManager.AppSettings["fromMapZoom"]);
                _toMapZoom = Convert.ToInt32(ConfigurationManager.AppSettings["toMapZoom"]);
            }
    
            private void btnTileProcess_Click(object sender, EventArgs e)
            {
                this.btnTileProcess.Enabled = false;
    
                Task.Factory.StartNew(() =>
                {
                    LogUtil.Log("开始处理");
                    Process();
                });
    
                Thread thread = new Thread(new ThreadStart(() =>
                {
                    int sleepInterval = 1000;
                    while (true)
                    {
                        Thread.Sleep(sleepInterval);
                        this.BeginInvoke(new Action(() =>
                        {
                            double totalSeconds = DateTime.Now.Subtract(_startTime).TotalSeconds;
                            int avg = (int)(_count / totalSeconds);
                            lblMsg.Text = string.Format("已处理 {0} 张瓦片图", _count);
                            if (_count - _lastCount > 0)
                            {
                                lblSpeed.Text = string.Format("当前速度:{0} 张/每秒,平均速度:{1} 张/每秒", (_count - _lastCount) * 1000.0 / sleepInterval, avg);
                            }
                            _lastCount = _count;
                        }));
                    }
                }));
                thread.IsBackground = true;
                thread.Start();
            }
    
            /// <summary>
            /// 瓦片纠偏处理
            /// </summary>
            private void Process()
            {
                _startTime = DateTime.Now;
                Regex regex = new Regex(@"\(d+)\(d+).png", RegexOptions.IgnoreCase);
                for (int i = _fromMapZoom; i <= _toMapZoom; i++)
                {
                    int deltaPixcelX = (int)Math.Round(_deltaPixcelX / Math.Round(Math.Pow(2, 18 - i)));
                    int deltaPixcelY = (int)Math.Round(_deltaPixcelY / Math.Round(Math.Pow(2, 18 - i)));
    
                    string[] fileArr = Directory.GetFiles(_inputPath + "\" + i, "*.*", SearchOption.AllDirectories);
                    foreach (string file in fileArr)
                    {
                        ThreadData data = new ThreadData();
                        data.File = file;
                        data.I = i;
                        data.DeltaPixcelX = deltaPixcelX;
                        data.DeltaPixcelY = deltaPixcelY;
    
                        ThreadUtil.Run((obj) =>
                        {
                            ThreadData d = obj as ThreadData;
    
                            Match match = regex.Match(d.File);
                            if (match.Success)
                            {
                                int x = Convert.ToInt32(match.Groups[1].Value);
                                int y = Convert.ToInt32(match.Groups[2].Value);
    
                                string pathTarget = string.Format(string.Format(@"{0}{1}{2}{3}.png", _outputPath, d.I, x, y));
                                if (!File.Exists(pathTarget))
                                {
                                    if (!Directory.Exists(Path.GetDirectoryName(pathTarget)))
                                    {
                                        Directory.CreateDirectory(Path.GetDirectoryName(pathTarget));
                                    }
                                    Bitmap bmpNew = new Bitmap(256, 256, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
                                    Graphics graph = Graphics.FromImage(bmpNew);
    
                                    int deltaX = data.DeltaPixcelX / 256;
                                    int deltaY = data.DeltaPixcelY / 256;
    
                                    //临时变量定义
                                    string pathSource = null;
                                    FileStream fs = null;
                                    byte[] bArr = null;
                                    MemoryStream ms = null;
                                    Bitmap bmpSource = null;
    
                                    //起始
                                    pathSource = string.Format(@"{0}{1}{2}{3}.png", _inputPath, d.I, x + deltaX, y + deltaY);
                                    if (File.Exists(pathSource))
                                    {
                                        fs = new FileStream(pathSource, FileMode.Open, FileAccess.Read);
                                        bArr = new byte[fs.Length];
                                        int readCount = fs.Read(bArr, 0, bArr.Length);
                                        ms = new MemoryStream(bArr, 0, readCount);
                                        bmpSource = new Bitmap(ms);
                                        graph.DrawImage(bmpSource, 0, 0, new RectangleF(data.DeltaPixcelX % 256, data.DeltaPixcelY % 256, 256 - data.DeltaPixcelX % 256, 256 - data.DeltaPixcelY % 256), GraphicsUnit.Pixel);
                                        graph.Flush();
    
                                        fs.Close();
                                        fs = null;
                                        ms.Close();
                                        ms = null;
                                        bmpSource.Dispose();
                                        bmpSource = null;
                                    }
    
                                    //右
                                    pathSource = string.Format(@"{0}{1}{2}{3}.png", _inputPath, d.I, x + deltaX + 1, y + deltaY);
                                    if (File.Exists(pathSource))
                                    {
                                        fs = new FileStream(pathSource, FileMode.Open, FileAccess.Read);
                                        bArr = new byte[fs.Length];
                                        int readCount = fs.Read(bArr, 0, bArr.Length);
                                        ms = new MemoryStream(bArr, 0, readCount);
                                        bmpSource = new Bitmap(ms);
                                        graph.DrawImage(bmpSource, 256 - data.DeltaPixcelX % 256, 0, new RectangleF(0, data.DeltaPixcelY % 256, data.DeltaPixcelX % 256, 256 - data.DeltaPixcelY % 256), GraphicsUnit.Pixel);
                                        graph.Flush();
    
                                        fs.Close();
                                        fs = null;
                                        ms.Close();
                                        ms = null;
                                        bmpSource.Dispose();
                                        bmpSource = null;
                                    }
    
                                    //下
                                    pathSource = string.Format(@"{0}{1}{2}{3}.png", _inputPath, d.I, x + deltaX, y + deltaY + 1);
                                    if (File.Exists(pathSource))
                                    {
                                        fs = new FileStream(pathSource, FileMode.Open, FileAccess.Read);
                                        bArr = new byte[fs.Length];
                                        int readCount = fs.Read(bArr, 0, bArr.Length);
                                        ms = new MemoryStream(bArr, 0, readCount);
                                        bmpSource = new Bitmap(ms);
                                        graph.DrawImage(bmpSource, 0, 256 - data.DeltaPixcelY % 256, new RectangleF(data.DeltaPixcelX % 256, 0, 256 - data.DeltaPixcelX % 256, data.DeltaPixcelY % 256), GraphicsUnit.Pixel);
                                        graph.Flush();
    
                                        fs.Close();
                                        fs = null;
                                        ms.Close();
                                        ms = null;
                                        bmpSource.Dispose();
                                        bmpSource = null;
                                    }
    
                                    //右下
                                    pathSource = string.Format(@"{0}{1}{2}{3}.png", _inputPath, d.I, x + deltaX + 1, y + deltaY + 1);
                                    if (File.Exists(pathSource))
                                    {
                                        fs = new FileStream(pathSource, FileMode.Open, FileAccess.Read);
                                        bArr = new byte[fs.Length];
                                        int readCount = fs.Read(bArr, 0, bArr.Length);
                                        ms = new MemoryStream(bArr, 0, readCount);
                                        bmpSource = new Bitmap(ms);
                                        graph.DrawImage(bmpSource, 256 - data.DeltaPixcelX % 256, 256 - data.DeltaPixcelY % 256, new RectangleF(0, 0, data.DeltaPixcelX % 256, data.DeltaPixcelY % 256), GraphicsUnit.Pixel);
                                        graph.Flush();
    
                                        fs.Close();
                                        fs = null;
                                        ms.Close();
                                        ms = null;
                                        bmpSource.Dispose();
                                        bmpSource = null;
                                    }
    
                                    bmpNew.Save(pathTarget);
                                    //bmpNew.Save("d:\_临时文件\1234.png"); //测试用
    
                                    bmpNew.Dispose();
                                    bmpNew = null;
                                    graph.Dispose();
                                    graph = null;
    
                                    _count++;
                                } //end if (!File.Exists(pathTarget))
                            } //end if (match.Success)
                        }, data, (ex) =>
                        {
                            this.BeginInvoke(new Action(() =>
                            {
                                lblErrorMsg.Text = "出错:" + ex.Message + "rn" + ex.StackTrace;
                                LogUtil.LogError(ex, "出错");
                            }));
                        }); //end ThreadUtil.Run
                    } //end foreach (string file in fileArr)
                } //end for (int i = _fromMapZoom; i <= _toMapZoom; i++)
            }
        }
    }
    
    for (var i=0;i<cars.length;i++)
    {
    document.write(cars[i] + "<br>");
    }
    

    图片 9图片 10

    View Code

     

    using System;
    using System.Collections.Concurrent;
    using System.Threading;
    using System.Threading.Tasks;
    
    namespace ConsoleApp1
    {
        class Program
        {
            static void Main(string[] args)
            {
                Task t = RunProgram();
                t.Wait();
            }
    
            static async Task RunProgram()
            {
                var taskStack = new ConcurrentStack<CustomTask>();
                var cts = new CancellationTokenSource();
    
                var taskSource = Task.Run(() => TaskProducer(taskStack));
    
                Task[] processors = new Task[4];
                for (int i = 1; i <= 4; i++)
                {
                    string processorId = i.ToString();
                    processors[i - 1] = Task.Run(
                        () => TaskProcessor(taskStack, "Processor " + processorId, cts.Token));
                }
    
                await taskSource;
                cts.CancelAfter(TimeSpan.FromSeconds(2));
    
                await Task.WhenAll(processors);
            }
    
            static async Task TaskProducer(ConcurrentStack<CustomTask> stack)
            {
                for (int i = 1; i <= 20; i++)
                {
                    await Task.Delay(50);
                    var workItem = new CustomTask { Id = i };
                    stack.Push(workItem);
                    Console.WriteLine("Task {0} has been posted", workItem.Id);
                }
            }
    
            static async Task TaskProcessor(
                ConcurrentStack<CustomTask> stack, string name, CancellationToken token)
            {
                await GetRandomDelay();
                do
                {
                    CustomTask workItem;
                    bool popSuccesful = stack.TryPop(out workItem);
                    if (popSuccesful)
                    {
                        Console.WriteLine("Task {0} has been processed by {1}", workItem.Id, name);
                    }
    
                    await GetRandomDelay();
                }
                while (!token.IsCancellationRequested);
            }
    
            static Task GetRandomDelay()
            {
                int delay = new Random(DateTime.Now.Millisecond).Next(1, 500);
                return Task.Delay(delay);
            }
    
            class CustomTask
            {
                public int Id { get; set; }
            }
        }
    }
    

    处理效率:我自己电脑每秒处理大约350张瓦片图,1到18级瓦片共100多万张图片,大约需要处理50分钟。

    in语句:

    Program

    瓦片图纠偏前后对比:

    var person={fname:"John",lname:"Doe",age:25};
    
    for (x in person)
      {
      txt=txt + person[x];
      }
    

    3、ConcurrentQueue类:安全队列

    图片 11

     

    图片 12图片 13

     

    .each:

    using System;
    using System.Collections.Concurrent;
    using System.Threading;
    using System.Threading.Tasks;
    
    namespace ConsoleApp1
    {
        class Program
        {
            static void Main(string[] args)
            {
                Task t = RunProgram();
                t.Wait();
            }
    
            static async Task RunProgram()
            {
                var taskQueue = new ConcurrentQueue<CustomTask>();
                var cts = new CancellationTokenSource();
    
                var taskSource = Task.Run(() => TaskProducer(taskQueue));
    
                Task[] processors = new Task[4];
                for (int i = 1; i <= 4; i++)
                {
                    string processorId = i.ToString();
                    processors[i - 1] = Task.Run(
                        () => TaskProcessor(taskQueue, "Processor " + processorId, cts.Token));
                }
    
                await taskSource;
                cts.CancelAfter(TimeSpan.FromSeconds(2));
    
                await Task.WhenAll(processors);
            }
    
            static async Task TaskProducer(ConcurrentQueue<CustomTask> queue)
            {
                for (int i = 1; i <= 20; i++)
                {
                    await Task.Delay(50);
                    var workItem = new CustomTask { Id = i };
                    queue.Enqueue(workItem);
                    Console.WriteLine("插入Task {0} has been posted ThreadID={1}", workItem.Id, Thread.CurrentThread.ManagedThreadId);
                }
            }
    
            static async Task TaskProcessor(
                ConcurrentQueue<CustomTask> queue, string name, CancellationToken token)
            {
                CustomTask workItem;
                bool dequeueSuccesful = false;
    
                await GetRandomDelay();
                do
                {
                    dequeueSuccesful = queue.TryDequeue(out workItem);
                    if (dequeueSuccesful)
                    {
                        Console.WriteLine("读取Task {0} has been processed by {1} ThreadID={2}",
                                            workItem.Id, name, Thread.CurrentThread.ManagedThreadId);
                    }
    
                    await GetRandomDelay();
                }
                while (!token.IsCancellationRequested);
            }
    
            static Task GetRandomDelay()
            {
                int delay = new Random(DateTime.Now.Millisecond).Next(1, 500);
                return Task.Delay(delay);
            }
    
            class CustomTask
            {
                public int Id { get; set; }
            }
        }
    }
    
     $("li").each(function(){
        alert($(this).text())
      });
    

    Program

     

    4、ConcurrentDictionary类
      ConcurrentDictionary类写操作比使用锁的通常字典(Dictionary)要慢的多,而读操作则要快些。因此对字典要大量的线程安全的读操作,ConcurrentDictionary类是最好的选择
      ConcurrentDictionary类的实现使用了细粒度锁(fine-grained locking)技术,这在多线程写入方面比使用锁的通常的字典(也被称为粗粒度锁)

    图片 14图片 15

    using System;
    using System.Collections.Concurrent;
    using System.Collections.Generic;
    using System.Diagnostics;
    
    namespace ConsoleApp1
    {
        class Program
        {
            static void Main(string[] args)
            {
                var concurrentDictionary = new ConcurrentDictionary<int, string>();
                var dictionary = new Dictionary<int, string>();
    
                var sw = new Stopwatch();
    
                sw.Start();
                for (int i = 0; i < 1000000; i++)
                {
                    lock (dictionary)
                    {
                        dictionary[i] = Item;
                    }
                }
                sw.Stop();
                Console.WriteLine("Writing to dictionary with a lock: {0}", sw.Elapsed);
    
                sw.Restart();
                for (int i = 0; i < 1000000; i++)
                {
                    concurrentDictionary[i] = Item;
                }
                sw.Stop();
                Console.WriteLine("Writing to a concurrent dictionary: {0}", sw.Elapsed);
    
                sw.Restart();
                for (int i = 0; i < 1000000; i++)
                {
                    lock (dictionary)
                    {
                        CurrentItem = dictionary[i];
                    }
                }
                sw.Stop();
                Console.WriteLine("Reading from dictionary with a lock: {0}", sw.Elapsed);
    
                sw.Restart();
                for (int i = 0; i < 1000000; i++)
                {
                    CurrentItem = concurrentDictionary[i];
                }
                sw.Stop();
                Console.WriteLine("Reading from a concurrent dictionary: {0}", sw.Elapsed);
            }
    
            const string Item = "Dictionary item";
            public static string CurrentItem;
        }
    }
    

    Program

    本文由金沙国际官网发布于编程,转载请注明出处:线程安全类型,谷歌瓦片地图纠偏

    关键词: