I am able to run WebBrowser in single threaded Env
But I am unable to run it in multithreaded env its throwing access violation error.
I am trying to run mutliple webbrowser instances and then taking screenshots.
Please have a look at the attached code.`
public class Image
{
public int id { get; set; }
public string url { get; set; }
}
internal class RenderMultipleImages
{
//Sample Urls which contains Ajax Calls
private static readonly List<Image> images = new List<Image>()
{
new Image(){id=1, url="www.abc1.com"},
new Image() {id=2,url= "www.abc2.com"},
new Image() {id=3,url= "www.abc3.com"},
new Image() {id=4,url= "www.abc4.com"},
new Image() {id=5, url="www.abc5.com"},
new Image() {id=6,url= "www.abc6.com"}
};
private static int _imageWidth = 1200;
private static int _imageHeight = 800;
public static void Render()
{
var startTime = DateTime.UtcNow;
var tasks = new List<Task>();
for (var i = 0; i < images.Count; i++)
{
var i1 = i;
var task = Task.Factory.StartNew(() => InvokeGenerateImage(images[i1].id, images[i1].url));
tasks.Add(task);
}
Task.WaitAll(tasks.ToArray());
Console.WriteLine("Time taken to finish: {0}", (DateTime.UtcNow - startTime).TotalSeconds);
}
private static void InvokeGenerateImage(int instanceNumber, string url)
{
var thread = new Thread(() => GenerateImage(instanceNumber, url));
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
thread.Join();
}
//[STAThread]
private static void GenerateImage(int instanceNumber, string url)
{
Console.WriteLine("Started instance number: {0}", instanceNumber);
var browser = new WebBrowser
{
ScrollBarsEnabled = false,
ScriptErrorsSuppressed = true,
Width = _imageWidth,
Height = _imageHeight
};
browser.Navigate(url);
while (browser.ReadyState != WebBrowserReadyState.Complete)
{
Application.DoEvents();
}
//As the url contains ajax calls am checking for the element id which tells us document loaded
while (browser.Document != null && browser.Document.GetElementById("chart-1") == null)
{
Application.DoEvents();
}
//Then screenshot
saveScreeshot(browser, instanceNumber);
browser.Dispose();
Console.WriteLine("Finished instance number: {0}", instanceNumber);
}
static void saveScreeshot(WebBrowser webb,int instance)
{
Bitmap bitmap = new Bitmap(1024, 768);
Rectangle bitmapRect = new Rectangle(0, 0, 1024, 768);
webb.Size = new Size(1024, 768);
webb.DrawToBitmap(bitmap, bitmapRect);
var name = instance + ".png";
bitmap.Save(name, ImageFormat.Png);
bitmap.Dispose();
}
}
}`
Related
I am tring to Scan document from my Application but excutution time my code stuck somewhere and Code did not worked. some time throw same error which I mention in Header. I given here my all code and also which I tried.
This is part of my code
private async void HomePageScanner()
{
try
{
string pdfFileName = string.Empty;
pdfFileName = Guid.NewGuid().ToString() + ".pdf";
//scanPdfFile = pdfFileName;
StorageFolder scanTempFolder = await KnownFolders.PicturesLibrary.CreateFolderAsync(Constants.PATH_TEMP_SCAN, CreationCollisionOption.OpenIfExists);
DeviceInformationDisplay selectedScanner = CmbScannerList.SelectedItem as DeviceInformationDisplay;
string ScannerID = selectedScanner.Id;
StorageFolder pdfFolder_DataFTP = await KnownFolders.PicturesLibrary.CreateFolderAsync(Constants.PATH_SCAN, CreationCollisionOption.OpenIfExists);
//var task = Task.Run(async () => { await ScanToFolder(ScannerID, scanTempFolder, pdfFileName, pdfFolder_DataFTP, null); });
//Task.Run(task);
ScanToFolder(ScannerID, scanTempFolder, pdfFileName, pdfFolder_DataFTP, null).RunSynchronously();
// await ScanToFolder(ScannerID, scanTempFolder, pdfFileName, pdfFolder_DataFTP, null);
}
catch (Exception ex) { new ExceptionHelper().AddException(ex.Message, this.ToString(), "HomePageScanner"); }
}
public async Task ScanToFolder(string deviceId, StorageFolder scanTempFolder, string pdfFileName, StorageFolder pdfFolder_dataFTP, StorageFolder pdfFolder_DataServer)
{
try
{
scanningDialog.ShowAsync();
_scanerTimer.Tick += _scanerTimer_Tick;
_scanerTimer.Interval = new TimeSpan(0, 0, 1);
_scanerTimer.Start();
// ImageScanner myScanner = await ImageScanner.FromIdAsync(deviceId);
ImageScanner myScanner = null;//= ImageScanner.FromIdAsync(deviceId);
await Task.Run(async () =>
{
myScanner = await ImageScanner.FromIdAsync(deviceId);
// var task = Task.Run(async () => { myScanner = await ImageScanner.FromIdAsync(deviceId);
_isScanContinue = true;
CancellationTokenSource source = new CancellationTokenSource();
CancellationToken token = source.Token;
if (myScanner.IsScanSourceSupported(ImageScannerScanSource.AutoConfigured))
{
myScanner.FlatbedConfiguration.Format = ImageScannerFormat.Jpeg; //Code Stuck here some time
for (int i = 0; i < _totalPageToScan; i++)
{
_pageCounter++;
if (i > 0)
{
scanningDialog.IsEnabled = false;
//scanningDialog.Hide();
ContentDialog scanConfirmationDialog = new ContentDialog()
{
Title = "Click OK button to scan the next page of your document",
CloseButtonText = "OK"
};
scanConfirmationDialog.Closed += ScanConfirmationDialog_Closed;
await scanConfirmationDialog.ShowAsync();
}
}
}
});
}
}
private void _scanerTimer_Tick(object sender, object e)
{
_scanCounter++;
if (_scanCounter == 30)
{
if (_isScanContinue == false)
{
CommonCls.ShowToastMessage("Something went wrong. please check your scanner");
this.Hide();
scanningDialog.DataContext = "Something went wrong!!";
scanningDialog.Hide();
}
}
}
I updated Complete Please View and Help me to solve this.
I hope a better solution which I needed most.
Thank You
You should think object oriented: one object is the scanner, one object is the dialog. They have to be completely independent each other and communicate via a clear interface. You can start from the code below where I skipped all the real scanning logic.
class ScannerInfoEventArgs : EventArgs
{
public string Message { get; set; }
public string ButtonText { get; set; }
public bool DialogEanbled { get; set; }
public bool Close { get; set; }
}
class Scanner
{
private int _totalPageToScan;
private int _pageCounter;
public event EventHandler<ScannerInfoEventArgs>? OnScannerInfo;
public delegate void ScannerInfoEventHandler(object sender, ScannerInfoEventArgs e);
public async Task HomePageScanner()
{
try
{
string pdfFileName = string.Empty;
pdfFileName = Guid.NewGuid().ToString() + ".pdf";
_totalPageToScan = 10; // or your calculation here
_pageCounter = 0;
await ScanToFolder("c:\\tempfolder", pdfFileName, "c:\\pdf_data", "c:\\data_server");
}
catch (Exception ex)
{
}
}
public bool IsScanSourceSupported(string source)
{
// yuor logic here
return true;
}
public enum ImageType
{
png,
jpeg
}
public ImageType imageType
{
get; set;
}
public async Task ScanToFolder(string scanTempFolder, string pdfFileName, string pdfFolder_dataFTP, string pdfFolder_DataServer)
{
try
{
await Task.Run(() =>
{
CancellationTokenSource source = new CancellationTokenSource();
CancellationToken token = source.Token;
if (this.IsScanSourceSupported("your parameter here"))
{
this.imageType = ImageType.jpeg; //Code Stuck here some time
for (int i = 0; i < _totalPageToScan; i++)
{
_pageCounter++;
if (i > 0)
{
ScannerInfoEventArgs ev = new ScannerInfoEventArgs() { Message = "Click OK button to scan the next page of your document", ButtonText = "OK", DialogEanbled = false, Close = false };
OnScannerInfo?.Invoke(this, ev);
if (ev.Close)
{
break;
}
}
if (i == 30) // or something more meaningful condition
{
ScannerInfoEventArgs ev = new ScannerInfoEventArgs() { Message = "Something went wrong.please check your scanner", ButtonText = "OK", DialogEanbled = true, Close = true };
OnScannerInfo?.Invoke(this, ev);
break;
}
}
}
});
}
catch (Exception)
{ }
}
}
class FakeDialog
{
public void ShowDialog(object sender, ScannerInfoEventArgs e)
{
Console.WriteLine(e.Message);
Console.WriteLine(e.ButtonText);
string asw = Console.ReadLine();
if (asw == "stop")
{
e.Close = true;
}
}
}
static class Program
{
static async Task Main()
{
var scanner = new Scanner();
var dialog = new FakeDialog();
scanner.OnScannerInfo += dialog.ShowDialog;
await scanner.HomePageScanner();
}
}
You should keep just the idea of object separation and asyn/await patter. Hope this can be a starting point.
Goal: To be able to handle thousands of request per second
Current Result: while the test code was at request 15k the http server had only processed about 3-400 request
My first iteration of this code I had set HTTP_HANDLER_THREADS to 2 where as after about 200 proccessed the server is overloaded and crashes.
I then up this number to 5 with similiar results.
I then up the number to 5000 and I got to around 800. This seems to me I am doing something very wrong because there is no way my system is running 5000 threads and based on running top -H -p <pid> I could see the thread pool and it did not open 5000 threads.
Very confused and would like help on how to adjust this to handle thousands of request
TestCase
class Program
{
private static readonly HttpClient client = new HttpClient();
private static int send_amount = 200000;
private static int sent_request = 0;
static void Main(string[] args)
{
Parallel.For(0, send_amount, i =>
{
var values = new Dictionary<string, string>{
{ "request", i.ToString() }
};
var content = new FormUrlEncodedContent(values);
var response = client.PostAsync("http://192.168.102.165:1990", content);
sent_request += 1;
Console.WriteLine($"Sent request {sent_request}/{send_amount}");
});
}
}
Constants
internal class Constants
{
public static bool IsDebugMode = false;
public const string PRODUCTION_IP = "192.168.102.165";
public const string DEVELOPMENT_IP = "192.168.102.165";
public const Int32 HTTP_PORT = 1990;
public const Int32 HTTPS_PORT = 1990;
public const Int32 HTTP_HANDLER_THREADS = 5000;
public static string[] SERVER_BINDS
{
get
{
var server_binds = new string[]
{
$"http://{(IsDebugMode ? DEVELOPMENT_IP : PRODUCTION_IP)}:{HTTP_PORT}/"
};
return server_binds;
}
}
}
Http server class
internal class HTTPServer
{
private readonly ProcessDataDelegate handler;
private readonly HttpListener listener;
public HTTPServer(HttpListener listener, string[] prefixes, ProcessDataDelegate handler)
{
this.listener = listener;
this.handler = handler;
for (var i = 0; i < prefixes.Length; i++)
{
listener.Prefixes.Add(prefixes[i]);
}
}
public void Start()
{
if (listener.IsListening)
{
return;
}
listener.Start();
for (var i = 0; i < Constants.HTTP_HANDLER_THREADS; i++)
{
listener.GetContextAsync().ContinueWith(ProcessRequestHandler);
}
}
public void Stop()
{
if (listener.IsListening)
{
listener.Stop();
}
}
private void ProcessRequestHandler(Task<HttpListenerContext> result)
{
var context = result.Result;
if (!listener.IsListening) return;
//Start a new listener which will replace this
listener.GetContextAsync().ContinueWith(ProcessRequestHandler);
//Read request
var request = new StreamReader(context.Request.InputStream).ReadToEnd();
//Prepare response
var response_bytes = handler.Invoke(request);
context.Response.ContentLength64 = response_bytes.Length;
var output = context.Response.OutputStream;
output.WriteAsync(response_bytes, 0, response_bytes.Length);
output.Close();
}
}
Program
class Program
{
private static Thread _console_thread;
private static int request_amount = 0;
static void Main(string[] args)
{
InitConsoleThread();
InitHttpServer();
}
private static void InitHttpServer()
{
var http_listener = new HttpListener();
var http_server = new HTTPServer.HTTPServer(http_listener, Constants.SERVER_BINDS, ProcessResponse);
http_server.Start();
}
private static byte[] ProcessResponse(string response)
{
request_amount += 1;
Console.WriteLine(request_amount);
//Sleep was added here to simulate the code doing something
Thread.Sleep(2000);
return new byte[0];
}
private static void InitConsoleThread()
{
_console_thread = new Thread(ConsoleLoop)
{
Name = "ConsoleThread"
};
_console_thread.Start();
}
private static void ConsoleLoop()
{
SpinWait.SpinUntil(() => false);
}
}
I'm setting up my architechture to use Cef.Offscreen. In order to make it easy to work with I have divided some parts. But I run into a problem that controller loading finshes and serves a view before everything has been able to load.
Here's my structure --> Controller
public ActionResult InitBrowser()
{
ICefSharpRenderer renderer = RendererSingelton.GetInstance();
//Try to render something in default appdomain
renderer.LoginToTradingView(null, null);
ViewBag.SiteTitle = BrowserActions.RunScriptInNamedBrowser("loginbrowser", #"(function() {return document.title;} )();");
ViewBag.ImagesixtyfourUrl = BrowserActions.TakeScreenshot("loginbrowser");
//this is returned to fast, we have to wait for all
return View();
}
I have this class to get do some basic actions and initialize if needed.
public class CefSharpRenderer : MarshalByRefObject, ICefSharpRenderer
{
private ChromiumWebBrowser _browser;
private TaskCompletionSource<JavascriptResponse> _taskCompletionSource;
private string _name;
public void LoginToTradingView(string url, string browserName)
{
CheckIfCefIsInitialized();
BrowserFactory.GetBrowserInstance(#"https://se.tradingview.com/", "loginbrowser");
}
public void CreateBrowserAndGoToUrl(string url, string browserName)
{
CheckIfCefIsInitialized();
BrowserFactory.GetBrowserInstance(url, "browserName");
}
public void CheckIfCefIsInitialized()
{
if (!Cef.IsInitialized)
{
var settings = new CefSettings();
var assemblyPath = Path.GetDirectoryName(new Uri(GetType().Assembly.CodeBase).LocalPath);
settings.BrowserSubprocessPath = Path.Combine(assemblyPath, "CefSharp.BrowserSubprocess.exe");
settings.ResourcesDirPath = assemblyPath;
settings.LocalesDirPath = Path.Combine(assemblyPath, "locales");
var osVersion = Environment.OSVersion;
//Disable GPU for Windows 7
if (osVersion.Version.Major == 6 && osVersion.Version.Minor == 1)
{
// Disable GPU in WPF and Offscreen examples until #1634 has been resolved
settings.CefCommandLineArgs.Add("disable-gpu", "1");
}
//Perform dependency check to make sure all relevant resources are in our output directory.
Cef.Initialize(settings, performDependencyCheck: false, cefApp: null);
}
}
}
I get my browserinstance here and connected the events to be fired.
public static class BrowserFactory
{
public static ChromiumWebBrowser GetBrowserInstance(string _url, string browsername)
{
if (!BrowserContainer.CheckIfBrowserExists(browsername))
{
ChromiumWebBrowser _browser = new ChromiumWebBrowser(_url);
_browser.LoadingStateChanged += BrowserEvents.OnLoadingStateChanged;
BrowserContainer.AddDataHolder(browsername, new DataBrowserHolder { BrowserName = browsername, ChromiumWebBrow = _browser });
return _browser;
}
return null;
}
}
Browserevent loads correct page.
public static class BrowserEvents
{
public static void OnLoadingStateChanged(object sender, LoadingStateChangedEventArgs args)
{
if (args.IsLoading == false)
{
ChromiumWebBrowser cwb = (ChromiumWebBrowser)sender;
if (cwb.Address == "https://se.tradingview.com/")
{
BrowserActions.LogInToTradingView("xxxxx", "yyyyyyy", "loginbrowser");
}
}
}
}
Last my browseractions, spare med for the thread sleeps it's just under construction and it works atm.
public static class BrowserActions
{
public static void LogInToTradingView(string twusername, string twpassword, string browserName)
{
ChromiumWebBrowser _dataholder = BrowserContainer.GetDataHolderByName(browserName).ChromiumWebBrow;
IFrame ifww = _dataholder.GetMainFrame();
// var lull = #"(function() { var serielength = TradingView.bottomWidgetBar._widgets.backtesting._reportWidgetsSet.reportWidget._data.filledOrders.length; return serielength; })();";
// JavascriptResponse _js = Task.Run(async () => { return await _browser.GetMainFrame().EvaluateScriptAsync(lull); }).Result;
ifww.ExecuteJavaScriptAsync(#"(function() { window.document.getElementsByClassName('tv-header__link tv-header__link--signin js-header__signin')[0].click();})();");
// var loginusernamescript =
var loginpasswordscript = #"(function() { window.document.getElementsByClassName('tv-control-material-input tv-signin-dialog__input tv-control-material-input__control')[1].value= " + twpassword + "; })();";
var clkloginbtn = #"(function() { document.getElementsByClassName('tv-button tv-button--no-border-radius tv-button--size_large tv-button--primary_ghost tv-button--loader')[0].click();})();";
Thread.Sleep(300);
ifww.ExecuteJavaScriptAsync(#"(function() { window.document.getElementsByClassName('tv-control-material-input tv-signin-dialog__input tv-control-material-input__control')[0].click();})();");
Thread.Sleep(50);
ifww.ExecuteJavaScriptAsync(#"(function() { window.document.getElementsByClassName('tv-control-material-input tv-signin-dialog__input tv-control-material-input__control')[0].value = '" + twusername + "';})();");
Thread.Sleep(50);
ifww.ExecuteJavaScriptAsync(#"(function() { window.document.getElementsByClassName('tv-control-material-input tv-signin-dialog__input tv-control-material-input__control')[1].click();})();");
Thread.Sleep(50);
ifww.ExecuteJavaScriptAsync(#"(function() { window.document.getElementsByClassName('tv-control-material-input tv-signin-dialog__input tv-control-material-input__control')[1].value = '" + twpassword + "';})();");
Thread.Sleep(50);
ifww.ExecuteJavaScriptAsync(#"(function() { document.getElementsByClassName('tv-button tv-button--no-border-radius tv-button--size_large tv-button--primary_ghost tv-button--loader')[0].click();})();");
}
public static string TakeScreenshot(string browserName)
{
try
{
Bitmap img = Task.Run(async () => { return await BrowserContainer.GetDataHolderByName(browserName).ChromiumWebBrow.ScreenshotAsync(); }).Result;
// object mgss = img.Clone();
string baseen = ExtraFunctions.ToBase64String(img, ImageFormat.Png);
return baseen;
}
catch (Exception e)
{
var x = e.InnerException;
return null;
}
}
public static string RunScriptInNamedBrowser(string browserName, string script)
{
try
{
string str = Task.Run(async () => { return await BrowserContainer.GetDataHolderByName(browserName).ChromiumWebBrow.GetMainFrame().EvaluateScriptAsync(script); }).Result.ToString();
// object mgss = img.Clone();
return str;
}
catch (Exception e)
{
var x = e.InnerException;
return null;
}
}
}
How can I get my browser actions to report back to my controller so that I can wait for them to finish?
For a Task asynchronous operation to report back, it's possible to use Progress<T>. How that's done is detailed in Enabling Progress and Cancellation in Async APIs. The key is:
var progressIndicator = new Progress<int>(ReportProgress);
This creates a Progress<T> object that can indicate how far a task is complete, and also call a custom method (ReportProgress) at set intervals. You can create a custom class if necessary instead of using int.
So your browser actions can report back to the controller with the progress reporting method until everything is complete.
In below application,
Producer method adding messages to a blocking collection.
In Consumer method, I'm consuming blocking collection and adding messages to a list and when size >= 240, writing that list to json file.
At some point I don't have any new messages in blocking collection, but in Consumer, I have a list of messages which is not >=240 in size, then in this case , the app is not able to write to a new JSON file (rest of the data).
How can I let the Consumer know that no new messages coming up, write whatever left with you in a new file?
Is this possible? let say Consumer will wait for 1 minute and if there is no new messages, then write whatever left in an new file?
Here is the code (here I'm adding 11 messages. Till 9 messages the batch size is 240 and it's generates a file, but message no 10 & 11 not able to write in new file),
class Program
{
private static List<Batch> batchList = new List<Batch>();
private static BlockingCollection<Message> messages = new BlockingCollection<Message>();
private static int maxbatchsize = 240;
private static int currentsize = 0;
private static void Producer()
{
int ctr = 1;
while (ctr <= 11)
{
messages.Add(new Message { Id = ctr, Name = $"Name-{ctr}" });
Thread.Sleep(1000);
ctr++;
}
}
private static void Consumer()
{
foreach (var message in messages.GetConsumingEnumerable())
{
var msg = JsonConvert.SerializeObject(message);
Console.WriteLine(msg);
if (currentsize + msg.Length >= maxbatchsize)
{
WriteToFile(batchList);
}
batchList.Add(new Batch { Message = message });
currentsize += msg.Length;
}
}
private static void WriteToFile(List<Batch> batchList)
{
using (StreamWriter outFile = System.IO.File.CreateText(Path.Combine(#"C:\TEMP", $"{DateTime.Now.ToString("yyyyMMddHHmmssfff")}.json")))
{
outFile.Write(JsonConvert.SerializeObject(batchList));
}
batchList.Clear();
currentsize = 0;
}
static void Main(string[] args)
{
var producer = Task.Factory.StartNew(() => Producer());
var consumer = Task.Factory.StartNew(() => Consumer());
Console.Read();
}
}
}
Supporting classes,
public class Message
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Batch
{
public Message Message { get; set; }
}
Update:
class Program
{
private static readonly List<Batch> BatchList = new List<Batch>();
private static readonly BlockingCollection<Message> Messages = new BlockingCollection<Message>();
private const int Maxbatchsize = 240;
private static int _currentsize;
private static void Producer()
{
int ctr = 1;
while (ctr <= 11)
{
Messages.Add(new Message { Id = ctr, Name = $"Name-{ctr}" });
Thread.Sleep(1000);
ctr++;
}
Messages.CompleteAdding();
}
private static void Consumer()
{
foreach (var message in Messages.GetConsumingEnumerable())
{
if (_currentsize >= Maxbatchsize)
{
var listToWrite = new Batch[BatchList.Count];
BatchList.CopyTo(listToWrite);
BatchList.Clear();
_currentsize = 0;
WriteToFile(listToWrite.ToList());
}
else
{
Thread.Sleep(1000);
if (Messages.IsAddingCompleted)
{
var remainSize = Messages.Select(JsonConvert.SerializeObject).Sum(x => x.Length);
if (remainSize == 0)
{
var lastMsg = JsonConvert.SerializeObject(message);
BatchList.Add(new Batch { Message = message });
_currentsize += lastMsg.Length;
Console.WriteLine(lastMsg);
var additionListToWrite = new Batch[BatchList.Count];
BatchList.CopyTo(additionListToWrite);
BatchList.Clear();
_currentsize = 0;
WriteToFile(additionListToWrite.ToList());
break;
}
}
}
var msg = JsonConvert.SerializeObject(message);
BatchList.Add(new Batch { Message = message });
_currentsize += msg.Length;
Console.WriteLine(msg);
}
}
private static void WriteToFile(List<Batch> listToWrite)
{
using (StreamWriter outFile = System.IO.File.CreateText(Path.Combine(#"C:\TEMP", $"{DateTime.Now.ToString("yyyyMMddHHmmssfff")}.json")))
{
outFile.Write(JsonConvert.SerializeObject(listToWrite));
}
}
static void Main(string[] args)
{
var producer = Task.Factory.StartNew(() => Producer());
var consumer = Task.Factory.StartNew(() => Consumer());
Console.Read();
}
}
I am new to MemoryMappedFiles. I am creating a file using MemoryMappedFile and I want to write a json string to it. But the problem is for the Write method of the MemoryMappedViewAccessor none of the overloads takes in a string. Please help.
public class ApplicationSettingsViewModel
{
ApplicationSettingsModel model;
MemoryMappedFile mmf = null;
//This is not a singleton class but I guess it has to be one but its ok for demonstration.
public ApplicationSettingsViewModel()
{
model = new ApplicationSettingsModel();
CreateFileUsingMemoryMap();
}
private void CreateFileUsingMemoryMap()
{
var info = Directory.CreateDirectory(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + "/" + model.Data.Settings.OrcaUISpecificSettings.TimeOutFolder);
string path = Path.Combine(info.FullName + "/" + model.Data.Settings.OrcaUISpecificSettings.File);
mmf = MemoryMappedFile.CreateFromFile(path, FileMode.CreateNew, "MyMemoryFile", 1024 * 1024, MemoryMappedFileAccess.ReadWrite);
}
public MemoryMappedViewAccessor GetAccessor()
{
MemoryMappedViewAccessor mmvAccessor = null;
if (mmf != null)
{
mmvAccessor = mmf.CreateViewAccessor();
}
return mmvAccessor;
}
}
public partial class MainWindow: Window
{
private readonly DispatcherTimer _activityTimer;
private Point _inactiveMousePosition = new Point(0, 0);
private ApplicationSettingsViewModel AppViewModel;
Mutex mutex = new Mutex(false, "OrcaGeneStudyMutex");
public MainWindow()
{
InitializeComponent();
}
public void WriteToFile(string status)
{
Root root = new Root();
root.AllApplications.Add(new DataToWrite()
{
AppName = "DevOrca", Status = status
});
var jsonString = JsonConvert.SerializeObject(root);
var Accessor = AppViewModel.GetAccessor();
mutex.WaitOne();
//Serialize Contents
Accessor.Write(1024, jsonString); //it gives a complilation error when i try to pass the json string,
}
}