Запись в файл из нескольких потоков асинхронно c #

Способ сделать это - передать массив date вместе с массивом data в методе plot. То есть с данным примером это будет:

import numpy as np
import datetime as dt
import matplotlib.pyplot as plt
from matplotlib.dates import (DateFormatter, rrulewrapper, RRuleLocator, YEARLY)

# Generate random data and dates
data = np.random.randn(10000)
start = dt.datetime.strptime("2019-03-14", "%Y-%m-%d")
end = dt.datetime.strptime("2046-07-30", "%Y-%m-%d")
date = [start + dt.timedelta(days=x) for x in range(0, (end-start).days)]

rule = rrulewrapper(YEARLY, byeaster=1, interval=2)
loc = RRuleLocator(rule)
formatter = DateFormatter('%d/%m/%y')

fig, ax = plt.subplots()
ax.xaxis.set_major_locator(loc)
ax.xaxis.set_major_formatter(formatter)
ax.xaxis.set_tick_params(rotation=30, labelsize=10)
plt.plot(date, data)
ax.set_xlim(min(date), max(date))
plt.show()

Тогда вы получите:

enter image description here

См. matplotlib.pyplot.plot () для получения дополнительной информации.

37
задан Jeffrey Cameron 17 August 2010 в 23:31
поделиться

4 ответа

Взгляните на Асинхронный ввод-вывод . Это освободит процессор, чтобы продолжить выполнение других задач.
Объедините с ReaderWriterLock , как упоминал @Jack B Nimble

Если по

записывает в файловую систему как как можно более эффективный

вы имеете в виду, как сделать фактический файловый ввод-вывод как можно более быстрым, вам будет трудно значительно его ускорить, диск просто физически медленнее. Может SSD?

14
ответ дан 27 November 2019 в 04:56
поделиться

Сохраните для входа с Очередью и несколькими потоками (.Net Core 2.2, к которому образцу Linux - протестированный)

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Text.RegularExpressions;
// add
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Net;
using System.Net.Sockets;
using System.Net.Security;
using System.Security.Authentication;
using System.IO;
using System.Timers;

namespace LogToFile
{
    class Program
    {
        public static Logger logger = new Logger("debug.log");

        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");

            logger.add("[001][LOGGER STARTING]");

            Thread t0 = new Thread(() => DoWork("t0"));
            t0.Start();

            Thread t1 = new Thread(() => DoWork("t1"));
            t1.Start();

            Thread t2 = new Thread(() => DoWork("t2"));
            t2.Start();

            Thread ts = new Thread(() => SaveWork());
            ts.Start();
        }

        public static void DoWork(string nr){
            while(true){
                logger.add("Hello from worker .... number " + nr);
                Thread.Sleep(300);
            }
        }

        public static void SaveWork(){
            while(true){
                logger.saveNow();
                Thread.Sleep(50);
            }
        }
    }

    class Logger
    {
        // Queue import: 
        // using System.Collections
        public Queue logs = new Queue();
        public string path = "debug.log";

        public Logger(string path){
            this.path = path;
        }

        public void add(string t){
            this.logs.Enqueue("[" + currTime() +"] " + t);
        }

        public void saveNow(){
            if(this.logs.Count > 0){
                // Get from queue
                string err = (string) this.logs.Dequeue();
                // Save to logs
                saveToFile(err, this.path);
            }
        }

        public bool saveToFile(string text, string path)
        {
            try{
                // string docPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
                // text = text + Environment.NewLine;
                using (StreamWriter sw = File.AppendText(path))
                {
                    sw.WriteLine(text);
                    sw.Close();
                }
            }catch(Exception e){
                // return to queue
                this.logs.Enqueue(text + "[SAVE_ERR]");
                return false;
            }
            return true;
        }

        public String currTime(){
            DateTime d = DateTime.UtcNow.ToLocalTime();
            return d.ToString("yyyy-MM-dd hh:mm:ss");
        }
    }
}

Компиляция (Сохраняют: LogToFile/Program.cs):

dotnet new console -o LogToFile
cd LogToFile
dotnet build
dotnet run

приложение Остановки CTRL+C и посмотрите файл журнала

cat debug.log
1
ответ дан 27 November 2019 в 04:56
поделиться

Можно использовать события для регистратора:

using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;

namespace EventLogger
{
    class Program
    {
        static void Main(string[] args)
        {                   
            // Event handler
            LogData ld = new LogData();
            // Logger
            Logger lo = new Logger();                    
            // Subscribe to event
            ld.MyEvent += lo.OnMyEvent;     
            // Thread loop
            int cnt = 1;
            while(cnt < 5){         
                Thread t = new Thread(() => RunMe(cnt, ld));
                t.Start();
                cnt++;
            }
            Console.WriteLine("While end");
        }

        // Thread worker
        public static void RunMe(int cnt, LogData ld){
            int nr = 0;
            while(true){
                nr++;
                // Add user and fire event
                ld.AddToLog(new User(){Name = "Log to file Thread" + cnt + " Count " + nr, Email = "em@em.xx"});
                Thread.Sleep(1);
            }
        }
    }

    class LogData
    {
        public delegate void MyEventHandler(object o, User u);
        public event MyEventHandler MyEvent;

        protected virtual void OnEvent(User u)
        {
            if(MyEvent != null){
                MyEvent(this, u);
            }

        }

        // Wywołaj
        public void AddToLog(User u){
            Console.WriteLine("Add to log.");

            // Odpal event
            OnEvent(u);

            Console.WriteLine("Added.");
        }
    }

    class User
    {
        public string Name = "";
        public string Email =  "";
    }

    class Logger
    {
        // Catch event
        public void OnMyEvent(object o, User u){
            try{
                Console.WriteLine("Added to file log! " + u.Name + " " + u.Email);
                File.AppendAllText(@"event.log", "Added to file log! " + u.Name + " " + u.Email+"\r\n");
            }catch(Exception e){
                Console.WriteLine("Error file log " + e);
            }
        }
    }
}
0
ответ дан 27 November 2019 в 04:56
поделиться

Используйте Reader / Writer блокировки для доступа файловый поток.

4
ответ дан 27 November 2019 в 04:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: