I wrote a basic server client program with c# and Unity to create my own network. During the process I wrote a byteBuffer to send data over the network. Everything works, but to send or receive the String. (I can send Integers and other dataforms succesfully).
My DLL file:
public class ByteBuffer : IDisposable
{
private List<byte> Buff;
private byte[] readBuff;
private int readpos;
private bool buffUpdated;
private bool disposedValue;
#region "Helpers"
public ByteBuffer()
{
this.buffUpdated = false;
this.disposedValue = false;
this.Buff = new List<byte>();
this.readpos = 0;
}
public long GetReadPos() =>
((long)this.readpos);
public byte[] ToArray() =>
this.Buff.ToArray();
public int Count() =>
this.Buff.Count;
public int Length() =>
(this.Count() - this.readpos);
public void Clear()
{
this.Buff.Clear();
this.readpos = 0;
}
#endregion
#region"Write Data"
public void WriteByte(byte Inputs)
{
Buff.Add(Inputs);
buffUpdated = true;
}
public void WriteBytes(byte[] Input)
{
this.Buff.AddRange(Input);
this.buffUpdated = true;
}
public void WriteInteger(int Input)
{
this.Buff.AddRange(BitConverter.GetBytes(Input));
this.buffUpdated = true;
}
public void WriteString(string Input)
{
this.Buff.AddRange(BitConverter.GetBytes(Input.Length));
this.Buff.AddRange(Encoding.ASCII.GetBytes(Input));
this.buffUpdated = true;
}
#endregion
#region "read Data"
public string ReadString(bool Peek = true)
{
int count = this.ReadInteger(true);
if (this.buffUpdated)
{
this.readBuff = this.Buff.ToArray();
this.buffUpdated = false;
}
string str = Encoding.ASCII.GetString(this.readBuff, this.readpos, count);
if ((Peek & (this.Buff.Count > this.readpos)) && (str.Length > 0))
{
this.readpos += count;
}
return str;
}
public byte ReadByte(bool Peek = true)
{
if (Buff.Count > readpos)
{
if (buffUpdated)
{
readBuff = Buff.ToArray();
buffUpdated = false;
}
byte ret = readBuff[readpos];
if (Peek & Buff.Count > readpos)
{
readpos += 1;
}
return ret;
}
else
{
throw new Exception("Byte Buffer is past its Limit!");
}
}
public byte[] ReadBytes(int Length, bool Peek = true)
{
if (this.buffUpdated)
{
this.readBuff = this.Buff.ToArray();
this.buffUpdated = false;
}
byte[] buffer = this.Buff.GetRange(this.readpos, Length).ToArray();
if (Peek)
{
this.readpos += Length;
}
return buffer;
}
public int ReadInteger(bool peek = true)
{
if (this.Buff.Count <= this.readpos)
{
throw new Exception("Byte Buffer Past Limit!");
}
if (this.buffUpdated)
{
this.readBuff = this.Buff.ToArray();
this.buffUpdated = false;
}
int num = BitConverter.ToInt32(this.readBuff, this.readpos);
if (peek & (this.Buff.Count > this.readpos))
{
this.readpos += 4;
}
return num;
}
#endregion
//IDisposable
protected virtual void Dispose(bool disposing)
{
if (!this.disposedValue)
{
if(disposing)
{
this.Buff.Clear();
}
this.readpos = 0;
}
this.disposedValue = true;
}
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
}
My SendData Class:
class ServerSendData{
public static ServerSendData instance = new ServerSendData();
public void SendDataToClient(int index, byte[] data)
{
ByteBuffer.ByteBuffer buffer = new ByteBuffer.ByteBuffer();
buffer.WriteBytes(data);
Network.Clients[index].myStream.BeginWrite(buffer.ToArray(), 0, buffer.ToArray().Length, null, null);
buffer = null;
}
public void SendWelcomeMessage(int index)
{
ByteBuffer.ByteBuffer buffer = new ByteBuffer.ByteBuffer();
buffer.WriteInteger(1); //paket nummer 1
buffer.WriteByte(2);
buffer.WriteString("A");
SendDataToClient(index, buffer.ToArray());
}
}
My HandleData Class:
public class ClientHandleData: MonoBehaviour{
public void HandleData(byte[]data)
{
int packetNum;
ByteBuffer.ByteBuffer buffer = new ByteBuffer.ByteBuffer();
buffer.WriteBytes(data);
packetNum = buffer.ReadInteger();
buffer = null;
if (packetNum == 0)
{
return;
}
else
{
HandleMessages(packetNum, data);
}
}
public void HandleMessages(int packetNum, byte[] data)
{
switch (packetNum)
{
case 1:
HandleWelcomeMessage(data);
break;
}
}
public void HandleWelcomeMessage(byte[] data)
{
ByteBuffer.ByteBuffer buffer = new ByteBuffer.ByteBuffer();
buffer.WriteBytes(data);
Debug.Log("Test");
int nummer = buffer.ReadInteger();
Debug.Log("Test1: "+nummer);
byte bt = buffer.ReadByte();
Debug.Log("Test2: " +bt);
message = buffer.ReadString();
Debug.Log("Test3");
Debug.Log(nummer);
Debug.Log(message);
Debug.Log(bt);
buffer = null;
}
}
My Log result looks like:
Test
Test1: 1
Test2: 2
Working with Unity 2018.2.11f1 personal 64 bit
Related
In continuation to my previous question C# Confluent.Kafka SetValueDeserializer object deserialization, I have tried creating my custom deserializer to deserialize protobuf message but getting this error:
System.InvalidOperationException: 'Type is not expected, and no contract can be inferred: Ileco.Chimp.Proto.FinalValue'
on line:
return Serializer.Deserialize<T>(stream);
Here my consumer and deserializer:
class Worker
{
public static void Consumer(string brokerList, string connStr, string consumergroup, string topic, string cacertlocation)
{
var config = new ConsumerConfig
{
BootstrapServers = brokerList,
SecurityProtocol = SecurityProtocol.SaslSsl,
SocketTimeoutMs = 60000, //this corresponds to the Consumer config `request.timeout.ms`
SessionTimeoutMs = 30000,
SaslMechanism = SaslMechanism.Plain,
SaslUsername = "$ConnectionString",
SaslPassword = connStr,
SslCaLocation = cacertlocation,
GroupId = consumergroup,
AutoOffsetReset = AutoOffsetReset.Earliest,
BrokerVersionFallback = "1.0.0", //Event Hubs for Kafka Ecosystems supports Kafka v1.0+, a fallback to an older API will fail
//Debug = "security,broker,protocol" //Uncomment for librdkafka debugging information
};
using (var consumer = new ConsumerBuilder<string, FinalValue>(config)
.SetKeyDeserializer(Deserializers.Utf8)
.SetValueDeserializer(new MyCustomDeserializer<FinalValue>())
.SetErrorHandler((_, e) => Console.WriteLine($"Error: {e.Reason}"))
.Build())
{
CancellationTokenSource cts = new CancellationTokenSource();
Console.CancelKeyPress += (_, e) => { e.Cancel = true; cts.Cancel(); };
consumer.Subscribe(topic);
Console.WriteLine("Consuming messages from topic: " + topic + ", broker(s): " + brokerList);
while (true)
{
try
{
var msg = consumer.Consume(cts.Token);
Console.WriteLine($"Received: '{msg.Message.Value}'");
//var bytes = Encoding.ASCII.GetBytes(msg.Message.Value);
//var fv = FromByteArray<ProtobufMsg>(bytes);
//var proto = ProtoDeserialize<ProtobufMsg>(bytes);
}
catch (ConsumeException e)
{
Console.WriteLine($"Consume error: {e.Error.Reason}");
}
catch (Exception e)
{
Console.WriteLine($"Error: {e.Message}");
}
}
}
}
}
public class MyCustomDeserializer<T> : IDeserializer<T>
{
public T Deserialize(ReadOnlySpan<byte> data, bool isNull, Confluent.Kafka.SerializationContext context)
{
using (var stream = new MemoryStream(data.ToArray()))
{
return Serializer.Deserialize<T>(stream);
}
}
}
FinalValue.proto
syntax = "proto3";
package ileco.chimp.proto;
import "google/protobuf/timestamp.proto";
import "google/protobuf/wrappers.proto";
option java_package = "ileco.chimp.proto";
option java_outer_classname = "FinalValueProtos";
message FinalValue {
google.protobuf.Timestamp timestamp = 1;
uint32 inputId = 2;
google.protobuf.DoubleValue value = 3;
uint32 sourceId = 4;
string inputGuid = 5;
}
FinalValue.cs
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: proto/FinalValue.proto
#pragma warning disable 1591, 0612, 3021
#region Designer generated code
using pb = global::Google.Protobuf;
using pbc = global::Google.Protobuf.Collections;
using pbr = global::Google.Protobuf.Reflection;
using scg = global::System.Collections.Generic;
namespace Ileco.Chimp.Proto {
/// <summary>Holder for reflection information generated from proto/FinalValue.proto</summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public static partial class FinalValueReflection {
#region Descriptor
/// <summary>File descriptor for proto/FinalValue.proto</summary>
public static pbr::FileDescriptor Descriptor {
get { return descriptor; }
}
private static pbr::FileDescriptor descriptor;
static FinalValueReflection() {
byte[] descriptorData = global::System.Convert.FromBase64String(
string.Concat(
"ChZwcm90by9GaW5hbFZhbHVlLnByb3RvEhFpbGVjby5jaGltcC5wcm90bxof",
"Z29vZ2xlL3Byb3RvYnVmL3RpbWVzdGFtcC5wcm90bxoeZ29vZ2xlL3Byb3Rv",
"YnVmL3dyYXBwZXJzLnByb3RvIp4BCgpGaW5hbFZhbHVlEi0KCXRpbWVzdGFt",
"cBgBIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASDwoHaW5wdXRJ",
"ZBgCIAEoDRIrCgV2YWx1ZRgDIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5Eb3Vi",
"bGVWYWx1ZRIQCghzb3VyY2VJZBgEIAEoDRIRCglpbnB1dEd1aWQYBSABKAlC",
"JQoRaWxlY28uY2hpbXAucHJvdG9CEEZpbmFsVmFsdWVQcm90b3NiBnByb3Rv",
"Mw=="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { global::Google.Protobuf.WellKnownTypes.TimestampReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.WrappersReflection.Descriptor, },
new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
new pbr::GeneratedClrTypeInfo(typeof(global::Ileco.Chimp.Proto.FinalValue), global::Ileco.Chimp.Proto.FinalValue.Parser, new[]{ "Timestamp", "InputId", "Value", "SourceId", "InputGuid" }, null, null, null)
}));
}
#endregion
}
#region Messages
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class FinalValue : pb::IMessage<FinalValue> {
private static readonly pb::MessageParser<FinalValue> _parser = new pb::MessageParser<FinalValue>(() => new FinalValue());
public static pb::MessageParser<FinalValue> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
get { return global::Ileco.Chimp.Proto.FinalValueReflection.Descriptor.MessageTypes[0]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
public FinalValue() {
OnConstruction();
}
partial void OnConstruction();
public FinalValue(FinalValue other) : this() {
Timestamp = other.timestamp_ != null ? other.Timestamp.Clone() : null;
inputId_ = other.inputId_;
Value = other.Value;
sourceId_ = other.sourceId_;
inputGuid_ = other.inputGuid_;
}
public FinalValue Clone() {
return new FinalValue(this);
}
/// <summary>Field number for the "timestamp" field.</summary>
public const int TimestampFieldNumber = 1;
private global::Google.Protobuf.WellKnownTypes.Timestamp timestamp_;
public global::Google.Protobuf.WellKnownTypes.Timestamp Timestamp {
get { return timestamp_; }
set {
timestamp_ = value;
}
}
/// <summary>Field number for the "inputId" field.</summary>
public const int InputIdFieldNumber = 2;
private uint inputId_;
public uint InputId {
get { return inputId_; }
set {
inputId_ = value;
}
}
/// <summary>Field number for the "value" field.</summary>
public const int ValueFieldNumber = 3;
private static readonly pb::FieldCodec<double?> _single_value_codec = pb::FieldCodec.ForStructWrapper<double>(26);
private double? value_;
public double? Value {
get { return value_; }
set {
value_ = value;
}
}
/// <summary>Field number for the "sourceId" field.</summary>
public const int SourceIdFieldNumber = 4;
private uint sourceId_;
public uint SourceId {
get { return sourceId_; }
set {
sourceId_ = value;
}
}
/// <summary>Field number for the "inputGuid" field.</summary>
public const int InputGuidFieldNumber = 5;
private string inputGuid_ = "";
public string InputGuid {
get { return inputGuid_; }
set {
inputGuid_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
public override bool Equals(object other) {
return Equals(other as FinalValue);
}
public bool Equals(FinalValue other) {
if (ReferenceEquals(other, null)) {
return false;
}
if (ReferenceEquals(other, this)) {
return true;
}
if (!object.Equals(Timestamp, other.Timestamp)) return false;
if (InputId != other.InputId) return false;
if (Value != other.Value) return false;
if (SourceId != other.SourceId) return false;
if (InputGuid != other.InputGuid) return false;
return true;
}
public override int GetHashCode() {
int hash = 1;
if (timestamp_ != null) hash ^= Timestamp.GetHashCode();
if (InputId != 0) hash ^= InputId.GetHashCode();
if (value_ != null) hash ^= Value.GetHashCode();
if (SourceId != 0) hash ^= SourceId.GetHashCode();
if (InputGuid.Length != 0) hash ^= InputGuid.GetHashCode();
return hash;
}
public override string ToString() {
return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
if (timestamp_ != null) {
output.WriteRawTag(10);
output.WriteMessage(Timestamp);
}
if (InputId != 0) {
output.WriteRawTag(16);
output.WriteUInt32(InputId);
}
if (value_ != null) {
_single_value_codec.WriteTagAndValue(output, Value);
}
if (SourceId != 0) {
output.WriteRawTag(32);
output.WriteUInt32(SourceId);
}
if (InputGuid.Length != 0) {
output.WriteRawTag(42);
output.WriteString(InputGuid);
}
}
public int CalculateSize() {
int size = 0;
if (timestamp_ != null) {
size += 1 + pb::CodedOutputStream.ComputeMessageSize(Timestamp);
}
if (InputId != 0) {
size += 1 + pb::CodedOutputStream.ComputeUInt32Size(InputId);
}
if (value_ != null) {
size += _single_value_codec.CalculateSizeWithTag(Value);
}
if (SourceId != 0) {
size += 1 + pb::CodedOutputStream.ComputeUInt32Size(SourceId);
}
if (InputGuid.Length != 0) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(InputGuid);
}
return size;
}
public void MergeFrom(FinalValue other) {
if (other == null) {
return;
}
if (other.timestamp_ != null) {
if (timestamp_ == null) {
timestamp_ = new global::Google.Protobuf.WellKnownTypes.Timestamp();
}
Timestamp.MergeFrom(other.Timestamp);
}
if (other.InputId != 0) {
InputId = other.InputId;
}
if (other.value_ != null) {
if (value_ == null || other.Value != 0D) {
Value = other.Value;
}
}
if (other.SourceId != 0) {
SourceId = other.SourceId;
}
if (other.InputGuid.Length != 0) {
InputGuid = other.InputGuid;
}
}
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
input.SkipLastField();
break;
case 10: {
if (timestamp_ == null) {
timestamp_ = new global::Google.Protobuf.WellKnownTypes.Timestamp();
}
input.ReadMessage(timestamp_);
break;
}
case 16: {
InputId = input.ReadUInt32();
break;
}
case 26: {
double? value = _single_value_codec.Read(input);
if (value_ == null || value != 0D) {
Value = value;
}
break;
}
case 32: {
SourceId = input.ReadUInt32();
break;
}
case 42: {
InputGuid = input.ReadString();
break;
}
}
}
}
}
#endregion
}
#endregion Designer generated code
As I noted yesterday, you appear to have used the Google .proto processing tools (protoc), but are using protobuf-net; if you want to use protobuf-net, similar command-line/IDE/build/etc tools exist that are compatible with the protobuf-net library, or you can use https://protogen.marcgravell.com/ for ad-hoc usage (to avoid having to install anything). Alternatively: continue using the Google schema tools, but use the Google library. Basically: they need to match.
The only minor gotcha here is that protobuf-net does not currently have explicit inbuilt support for DoubleValue; for reference: this can be considered as simply:
namespace Google.Protobuf.WellKnownTypes
{
[ProtoContract]
public sealed class DoubleValue
{
[ProtoMember(1)]
public double Value {get;set;}
}
}
I should probably find time to take all the types from wrappers.proto and allow them as double?, float?, long? etc - but it will need an additional marker, as Nullable<T> is already handled but with a different meaning (i.e. optional in .proto terms)
After background process DoWork() the control is exit from the block but it never fire a RunWorkerCompleted() and one more thing is isBusy is still true
Please help me
Dispatcher.CurrentDispatcher.Invoke(new Action(() =>
{
sendFile.Send();
}));
This is my FileReadWrite.cs file
Whenever I used this file in xaml class file it worked but there I am using Dispatcher in DispatcherObject class from WindowBase.dll but in another .cs file I can't use that DispatcherObject class that's why I am using Dispatcher.CurrentDispatcher.Invoke()
public class FileReadWrite
{
public int SourceId;
public int DestinationId;
public string FileName;
public WebSocket WebSocket;
public int SplitSize;
public int ReferenceId;
BinaryWriter _binaryWriter;
public int _totalsequence = 0;
public int progvalue;
public static double totallength;
public static double calculate, sendlen;
public static int post;
public double calc, count, len, sentsize;
public static int FileSendCount = 0;
public static List<byte[]> FileList = new List<byte[]>();
public BackgroundWorker _worker = new BackgroundWorker();
public FileReadWrite()
{
_worker.DoWork += _worker_DoWork;
_worker.RunWorkerCompleted += _worker_RunWorkerCompleted;
}
void _worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
FileCloseMessage fileclosemsg = new FileCloseMessage();
fileclosemsg.Source = SourceId;
fileclosemsg.Destination = DestinationId;
fileclosemsg.Date = DateTime.Now;
fileclosemsg.Sequenceno = 0;
fileclosemsg.totalsequence = _totalsequence;
byte[] bytess = fileclosemsg.GetBytes();
FileList.Add(bytess);
}
void _worker_DoWork(object sender, DoWorkEventArgs e)
{
using (BinaryReader b = new BinaryReader(File.Open(FileName, FileMode.Open)))
{
int pos = 0;
int length = (int)b.BaseStream.Length;
totallength = Convert.ToDouble(length);
byte[] bytes = new byte[SplitSize];
while (pos < length)
{
if (pos + SplitSize > length)
{
bytes = new byte[length - pos];
}
len = Convert.ToDouble(length);
bytes = b.ReadBytes(bytes.Length);
FileContentMesssage fileContentMesssage = new FileContentMesssage();
fileContentMesssage.Content = bytes;
fileContentMesssage.ReferenceId = ReferenceId;
pos += SplitSize;
fileContentMesssage.SequenceNo = pos / SplitSize;
_totalsequence++;
byte[] filebytes = fileContentMesssage.GetBytes();
FileList.Add(filebytes);
}
}
}
public async void Send()
{
_worker.RunWorkerAsync();
}
public void FileReceive(byte[] bytes)
{
try
{
if (_binaryWriter != null)
_binaryWriter.Write(bytes);
}
catch (Exception ex)
{
}
}
public string FileCreate()
{
string path = AppDomain.CurrentDomain.BaseDirectory;
string filename = Path.GetFileName(FileName);
string fullfilename = string.Format("{0}{1}", path, filename);
_binaryWriter = new BinaryWriter(File.Open(fullfilename, FileMode.Create));
return (fullfilename);
}
public void FileClose()
{
_binaryWriter.Close();
}
public byte[] FileSend()
{
byte[] bytess = FileList[FileSendCount];
FileSendCount++;
return (bytess);
}
public void FileClosed()
{
FileSendCount = 0;
FileList.Clear();
post = 0;
sendlen = 0;
calculate = 0;
totallength = 0;
_totalsequence = 0;
}
}
I'm using a BinaryFormatter to serialize and deserialize a list of items into byte[] arrays, and I've noticed that for a significant number of elements in the list my UI will hang or have "hiccups". When I say significant, I'm talking about 10K items (each with a collection of items of their own).
What is interesting is that the serialization and deserialization occurs on a separate thread, so I would not have thought UI interruptions would have occurred. I was just curious if anyone has dealt with anything similar, and if there are any workarounds.
The code snippets below are from the stripped down sol'n that I'm testing with. While I'm using the BinaryFormatter to read and write to disk here as well, the part I'm more interested in is what is in the SerializationHelper class (where it is being done in memory).
I also realize that the UI thread will be interrupted to post status updates, however those are negligible. I'm noticing the UI hangs while BinaryFormatter.Deserialize is executing and nothing is being updated on the UI.
DataReader:
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
namespace SerializationTesting
{
internal class DataReader : DataIOBase
{
#region Constants
private const int MAX_STEPS = 2;
#endregion
#region Declarations
private string _file;
#endregion
public DataReader(string file)
{
_file = file;
}
protected override void DoWork()
{
UpdateStatus(0, MAX_STEPS, "Reading from file...");
byte[] serializedData = ReadFromDisk();
UpdateStatus(1, MAX_STEPS, "Deserializing data...");
if (serializedData == null) return;
DeserializeData(serializedData);
UpdateStatus(2, MAX_STEPS, "Finished!");
}
private byte[] ReadFromDisk()
{
byte[] serializedData = null;
using (FileStream stream = new FileStream(_file, FileMode.Open, FileAccess.Read))
{
using (BufferedStream bufferedStream = new BufferedStream(stream))
{
BinaryFormatter formatter = new BinaryFormatter();
serializedData = formatter.Deserialize(bufferedStream) as byte[];
}
}
return serializedData;
}
private void DeserializeData(byte[] serializedData)
{
List<Data> dataList = SerializationHelper.Deserialize(serializedData, new List<Data>());
dataList.Clear();
dataList = null;
serializedData = null;
}
}
}
DataWriter:
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
namespace SerializationTesting
{
internal class DataWriter : DataIOBase
{
#region Declarations
private string _file;
private int _count;
#endregion
public DataWriter(string file, int count)
{
_file = file;
_count = count;
}
protected override void DoWork()
{
int maxSteps = _count + 2;
UpdateStatus(0, maxSteps, "Creating data...");
List<Data> dataList = CreateData(maxSteps);
UpdateStatus(_count, maxSteps, "Serializing data...");
byte[] serializedData = SerializationHelper.Serialize(dataList, null);
UpdateStatus(_count + 1, maxSteps, "Writing to file...");
WriteToDisk(serializedData, maxSteps);
serializedData = null;
dataList.Clear();
dataList = null;
UpdateStatus(maxSteps, maxSteps, "Finished!");
}
private List<Data> CreateData(int maxSteps)
{
List<Data> dataList = new List<Data>();
for (int i = 0; i < _count; i++)
{
UpdateStatus(i, maxSteps, string.Format("Creating item {0}...", i + 1));
Data data = new Data();
dataList.Add(data);
}
return dataList;
}
private void WriteToDisk(byte[] serializedData, int maxSteps)
{
using (FileStream stream = new FileStream(_file, FileMode.Create, FileAccess.Write))
{
using (BufferedStream bufferedStream = new BufferedStream(stream))
{
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(bufferedStream, serializedData);
}
}
}
}
}
DataIOBase:
using System.Diagnostics;
using System.Threading;
namespace SerializationTesting
{
internal abstract class DataIOBase
{
#region Declarations
private Thread _thread;
#endregion
#region Events
public event UpdateStatusHandler OnStatusChange;
public event ProcessCompleteHandler OnComplete;
#endregion
public void Start()
{
KillThread();
_thread = new Thread(new ThreadStart(ThreadBody));
_thread.Start();
}
private void KillThread()
{
if (_thread == null) return;
if (!_thread.IsAlive) return;
try
{
_thread.Abort();
}
catch { }
}
private void ThreadBody()
{
Stopwatch sw = new Stopwatch();
sw.Start();
try
{
DoWork();
}
catch { }
finally
{
sw.Stop();
if (OnComplete != null)
{
OnComplete(sw.ElapsedMilliseconds);
}
}
}
protected abstract void DoWork();
protected void UpdateStatus(int curr, int max, string status)
{
if (OnStatusChange == null) return;
OnStatusChange(curr, max, status);
}
}
}
Data:
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Security.Permissions;
namespace SerializationTesting
{
[Serializable]
public class Data : ISerializable
{
#region Static Members
private static readonly int COLLECTION_SIZE_MIN = 1;
private static readonly int COLLECTION_SIZE_MAX = 20;
private static Random _rand = null;
private static Random Rand
{
get
{
if (_rand == null)
{
_rand = new Random();
}
return _rand;
}
}
#endregion
#region Instance Properties
public string Name1 { get; set; }
public string Name2 { get; set; }
public string Name3 { get; set; }
public string Name4 { get; set; }
public string Name5 { get; set; }
public int Num1 { get; set; }
public int Num2 { get; set; }
public int Num3 { get; set; }
public int Num4 { get; set; }
public int Num5 { get; set; }
public bool Bool1 { get; set; }
public bool Bool2 { get; set; }
public bool Bool3 { get; set; }
public bool Bool4 { get; set; }
public bool Bool5 { get; set; }
public Dictionary<int, Data> Collection { get; set; }
#endregion
public Data(bool createCollection = true)
{
Init(createCollection);
}
#region Init
private void Init(bool createCollection)
{
try
{
Name1 = CreateString();
Name2 = CreateString();
Name3 = CreateString();
Name4 = CreateString();
Name5 = CreateString();
Num1 = CreateInt();
Num2 = CreateInt();
Num3 = CreateInt();
Num4 = CreateInt();
Num5 = CreateInt();
Bool1 = CreateBool();
Bool2 = CreateBool();
Bool3 = CreateBool();
Bool4 = CreateBool();
Bool5 = CreateBool();
CreateCollection(createCollection);
}
catch { }
}
private string CreateString()
{
int length = Rand.Next(1, 31);
char[] value = new char[length];
for (int i = 0; i < length; i++)
{
int charValue = Rand.Next(48, 91);
value[i] = (char)i;
}
return new string(value);
}
private int CreateInt()
{
return Rand.Next(1, 11);
}
private bool CreateBool()
{
int value = Rand.Next(0, 2);
return value == 0 ? false : true;
}
private void CreateCollection(bool populateCollection)
{
Collection = new Dictionary<int, Data>();
if (!populateCollection) return;
int count = Rand.Next(COLLECTION_SIZE_MIN, COLLECTION_SIZE_MAX + 1);
for (int i = 0; i < count; i++)
{
Data data = new Data(false);
Collection.Add(i, data);
}
}
#endregion
#region Serialization
public Data(SerializationInfo info, StreamingContext context)
{
SerializationHelper sh = new SerializationHelper(info);
Name1 = sh.GetItem("Name1", string.Empty);
Name2 = sh.GetItem("Name2", string.Empty);
Name3 = sh.GetItem("Name3", string.Empty);
Name4 = sh.GetItem("Name4", string.Empty);
Name5 = sh.GetItem("Name5", string.Empty);
Num1 = sh.GetItem("Num1", -1);
Num2 = sh.GetItem("Num2", -1);
Num3 = sh.GetItem("Num3", -1);
Num4 = sh.GetItem("Num4", -1);
Num5 = sh.GetItem("Num5", -1);
Bool1 = sh.GetItem("Bool1", false);
Bool2 = sh.GetItem("Bool2", false);
Bool3 = sh.GetItem("Bool3", false);
Bool4 = sh.GetItem("Bool4", false);
Bool5 = sh.GetItem("Bool5", false);
Collection = sh.GetItem("Collection", new Dictionary<int, Data>());
}
[SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)]
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("Name1", Name1);
info.AddValue("Name2", Name2);
info.AddValue("Name3", Name3);
info.AddValue("Name4", Name4);
info.AddValue("Name5", Name5);
info.AddValue("Num1", Num1);
info.AddValue("Num2", Num2);
info.AddValue("Num3", Num3);
info.AddValue("Num4", Num4);
info.AddValue("Num5", Num5);
info.AddValue("Bool1", Bool1);
info.AddValue("Bool2", Bool2);
info.AddValue("Bool3", Bool3);
info.AddValue("Bool4", Bool4);
info.AddValue("Bool5", Bool5);
info.AddValue("Collection", Collection);
}
#endregion
}
}
SerializationHelper:
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
namespace SerializationTesting
{
public class SerializationHelper
{
#region Declarations
private SerializationInfo _serializationInfo;
#endregion
public SerializationHelper(SerializationInfo serializationInfo)
{
_serializationInfo = serializationInfo;
}
#region Get Item
public T GetItem<T>(string item, T defaultValue)
{
try
{
object value = _serializationInfo.GetValue(item, typeof(T));
return (T)value;
}
catch
{
return defaultValue;
}
}
#endregion
#region Binary Serialization
public static T Deserialize<T>(byte[] serializedObject, T defaultValue, SerializationBinder binder = null)
{
if (serializedObject == null) return defaultValue;
try
{
object deserializedObject;
BinaryFormatter binaryFormatter = new BinaryFormatter();
if (binder != null)
{
binaryFormatter.Binder = binder;
}
using (MemoryStream stream = new MemoryStream(serializedObject))
{
stream.Seek(0, 0);
deserializedObject = binaryFormatter.Deserialize(stream);
}
if (!(deserializedObject is T))
{
return defaultValue;
}
return (T)deserializedObject;
}
catch
{
return defaultValue;
}
}
public static byte[] Serialize(object o, byte[] defaultValue, SerializationBinder binder = null)
{
if (o == null) return null;
try
{
byte[] serializedObject;
BinaryFormatter binaryFormatter = new BinaryFormatter();
if (binder != null)
{
binaryFormatter.Binder = binder;
}
using (MemoryStream stream = new MemoryStream())
{
binaryFormatter.Serialize(stream, o);
serializedObject = stream.ToArray();
}
return serializedObject;
}
catch
{
return defaultValue;
}
}
#endregion
}
}
FYI, as of Nov 2020, MS recommends not using using BinaryFormatter in your code.
Instead, consider using JsonSerializer or XmlSerializer. For more information, see BinaryFormatter security guide.
I have this program that creates threads on which i must create queue folders and
check them for files.
Now I noticed my program failed after processing a huge number of files without problems.
I produces a UnauthorizedAccessException so I went looking for that folder and it appears
the folder has been locked out totally?!
Could this be my anti-virus blocking access or is it something I must fix on my thread?
public class worker
{
public bool Stopping = false;
private System.Timers.Timer _timer;
private List<string> _files;
#region Feedback
public event FeedbackHandler Feedback;
public delegate void FeedbackHandler(object sender, string text);
#endregion
#region Properties
private string _name;
public string Name
{
get { return _name; }
}
private string _folder;
public string Folder
{
get { return _folder; }
set { _folder = value; }
}
private string _outfolder = Path.Combine(shared.Root, "out");
public string Outfolder
{
get { return _outfolder; }
set { _outfolder = value; }
}
private string _backupfolder = Path.Combine(shared.Root, "backup");
public string Backupfolder
{
get { return _backupfolder; }
set { _backupfolder = value; }
}
private string _filter = "*.*";
public string Filter
{
get { return _filter; }
set { _filter = value; }
}
private SearchOption _subfolders = SearchOption.TopDirectoryOnly;
public bool Subfolders
{
get { return (_subfolders == SearchOption.AllDirectories); }
set { if (value) { _subfolders = SearchOption.AllDirectories; } else { _subfolders = SearchOption.TopDirectoryOnly; } }
}
#endregion
#region Constructor
public worker(string Name)
{
_name = Name;
_folder = Path.Combine(shared.Root, "queues");
_folder = Path.Combine(_folder, Name);
}
#endregion
#region Destructor
~worker()
{
}
#endregion
#region Control
public void Start()
{
Stopping = false;
Directory.CreateDirectory(_folder);
_timer = new System.Timers.Timer(1);
_timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed);
_timer.Start();
Feedback(this, "[" + _name + "] started!");
}
public void Stop()
{
Stopping = true;
Feedback(this, "[" + _name + "] stopped...");
}
void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
if (Stopping)
{
_timer.Stop();
_files.Clear();
return;
}
_timer.Stop();
Process();
_timer.Start();
}
#endregion
void Process()
{
if (Directory.Exists(_folder))
{
_files = Directory.GetFiles(_folder, _filter, _subfolders).ToList();
foreach (string _file in _files.ToArray())
{
if (Stopping) { break; }
document _document = new document(_file);
_document.Copy(_backupfolder);
_document.Move(_outfolder);
}
_files = new List<string>();
}
}
}
public class document
{
private string _header;
#region Feedback
public event FeedbackHandler Feedback;
public delegate void FeedbackHandler(object sender, string text);
#endregion
#region Properties
private string _file;
public string File
{
get { return _file; }
}
private job _job;
public job Job
{
get { return _job; }
}
#endregion
#region Constructor
public document(string File)
{
_file = File;
_header = shared.FileOperations.ReadHeader(_file);
_job = new job(_file, _header);
_job.ReadHeader();
}
#endregion Constructor
public void Copy(string Folder)
{
string _backupfile;
_backupfile = Path.Combine(Folder,_job.Name);
_backupfile = Path.Combine(_backupfile,_job.Company);
_backupfile = Path.Combine(_backupfile, DateTime.Now.ToString("yyyy"));
_backupfile = Path.Combine(_backupfile, DateTime.Now.ToString("MMMM"));
Directory.CreateDirectory(_backupfile);
_backupfile = Path.Combine(_backupfile, Path.GetFileName(_file));
shared.FileOperations.CopyFile(_file, _backupfile, true);
}
public void Move(string Folder)
{
string _outfile;
_outfile = Path.Combine(Folder, Path.GetFileNameWithoutExtension(_file));
shared.FileOperations.MoveFile(_file, _outfile, true);
}
}
public struct shared
{
public static string Root
{
get
{
string _base = System.AppDomain.CurrentDomain.BaseDirectory.ToString();
return Directory.GetParent(_base).Parent.FullName.ToString();
}
}
public struct Patterns
{
public const string Header = #"\^?JOB\s(?<JOB>[a-zA-Z0-9]+[0-9]{3})[D]?(?<ACTION>[JFE]+)(?<COMPANY>[A-Z]{2,2})\s" +
#"(?<EMAIL>-emto=.*)?" +
#"-C(?<COPIES>[0-9]{2,2})\s" +
#"-Z""(?<PRINTER>[A-Z0-9]+)""\s" +
#"(?:\^?PAGE 01|(?<FAX>\^?FAX.*)\s\^?PAGE 01?)";
public const string Jump = #"\^PAGE\s[0-9]+";
public const string Pages = #"(\$?PAGE\s)";
public const string Fax = #"\^?FAX FROM_COMPANY\s""(?<FROM>.*)""\s" +
#"\^?FAX FROM_FAX_NUM\s""(?<FFAX>.*)""\s" +
#"\^?FAX FROM_NAME\s""(?<FNAME>.*)""\s" +
#"\^?FAX TO_FAX_NUM\s""(?<TFAX>.*)""\s" +
#"\^?FAX TO_COMPANY\s""(?<TO>.*)""\s" +
#"\^?FAX TO_NAME\s""(?<TNAME>.*)""\s" +
#"\^?FAX WHO\s""(?<WHO>.*)""\s" +
#"\^?FAX ID\s+(?<ID>.*)";
public const string Mail = #"-em([^\s=]+)=(""[^""]*""|[^\s]+)";
public const string Seperator = #"^";
}
public struct FileOperations
{
// Encoding
public static Encoding ReadEncoding = Encoding.GetEncoding(1252);
public static Encoding WriteEncoding = Encoding.UTF8;
// Timeouts
static int Timeout = 1;
static int FileTimeout = 10000; // 10 seconds/file permitted..
// Header
public static string ReadHeader(string SourceFile)
{
return ReadHeader(SourceFile, Patterns.Jump);
}
public static string ReadHeader(string SourceFile, string Beacon)
{
WaitFile(SourceFile);
string r = null;
string l = null;
try
{
StreamReader _reader = new StreamReader(SourceFile, ReadEncoding);
Match _match;
do
{
l = _reader.ReadLine();
r += l + " ";
_match = Regex.Match(l, Beacon);
} while (!_match.Success);
_reader.Close();
}
catch (Exception ex)
{
// todo
if (Debugger.IsAttached) { throw ex; }
}
return r;
}
// Read Contents
public static List<string> ReadFile(string SourceFile)
{
return ReadFile(SourceFile, Patterns.Seperator);
}
public static List<string> ReadFile(string SourceFile, string Seperator)
{
WaitFile(SourceFile);
List<string> lines = new List<string>();
try
{
StreamReader sr = new StreamReader(SourceFile, Encoding.GetEncoding(1250));
string tmp = null;
string line = null;
while (!sr.EndOfStream)
{
line = sr.ReadLine();
if (!string.IsNullOrEmpty(line) && line.Substring(0, 1) == Seperator)
{
if (!string.IsNullOrEmpty(tmp))
{
lines.Add(tmp);
}
tmp = line.Replace(Seperator, "^");
}
else
{
tmp += Environment.NewLine + line;
}
}
sr.Close();
if (!string.IsNullOrEmpty(tmp))
{
lines.Add(tmp);
}
}
catch (Exception ex)
{
// todo
if (Debugger.IsAttached) {throw ex;}
}
return lines;
}
// Write Contents
public static void WriteFile(string DestinationFile, List<string> Lines)
{
try
{
File.WriteAllLines(DestinationFile, Lines.ToArray(), WriteEncoding);
}
catch (Exception ex)
{
// todo
if (Debugger.IsAttached) { throw ex; }
}
}
public static void WriteFile(string DestinationFile, string Contents)
{
try
{
File.WriteAllText(DestinationFile, Contents);
}
catch (Exception ex)
{
// todo
if (Debugger.IsAttached) { throw ex; }
}
}
// Move File
public static void MoveFile(string SourceFile, string DestinationFile, bool Overwrite)
{
WaitFile(SourceFile);
try
{
string _count = null;
string _destination = Path.GetDirectoryName(DestinationFile);
string _file = Path.GetFileNameWithoutExtension(DestinationFile);
string _extension = Path.GetExtension(DestinationFile);
string[] _files = Directory.GetFiles(_destination, _file + "*");
if (_files.Length > 0)
{
if (Overwrite)
{
for (int x = 0; x <= _files.Length - 1; x++)
{
File.Delete(_files[x]);
}
}
else
{
_count = "_" + (_files.Length - 1).ToString("D4");
}
}
DestinationFile = Path.Combine(_destination, _file + _count + _extension);
File.Move(SourceFile, DestinationFile);
}
catch (Exception ex)
{
if (Debugger.IsAttached) { throw ex; }
}
}
public static void CopyFile(string SourceFile, string DestinationFile, bool Overwrite)
{
WaitFile(SourceFile);
try
{
string _count = null;
string _destination = Path.GetDirectoryName(DestinationFile);
string _file = Path.GetFileNameWithoutExtension(DestinationFile);
string _extension = Path.GetExtension(DestinationFile);
string[] _files = Directory.GetFiles(_destination, _file + "*");
if (_files.Length > 0)
{
if (Overwrite)
{
for (int x = 0; x <= _files.Length - 1; x++)
{
File.Delete(_files[x]);
}
}
else
{
_count = "_" + (_files.Length - 1).ToString("D4");
}
}
DestinationFile = Path.Combine(_destination, _file + _count + _extension);
File.Copy(SourceFile, DestinationFile);
}
catch (Exception ex)
{
if (Debugger.IsAttached) { throw ex; }
}
}
// Delete File
public static void DeleteFile(string SourceFile)
{
WaitFile(SourceFile);
try
{
File.Delete(SourceFile);
}
catch (Exception ex)
{
// todo
if (Debugger.IsAttached) { throw ex; }
}
}
// Check File
static void WaitFile(string SourceFile)
{
Timeout = 1;
while (!File.Exists(SourceFile))
{
System.Threading.Thread.Sleep(Timeout);
Timeout++;
if (Timeout == FileTimeout)
{
// todo
if (Debugger.IsAttached) { throw new Exception("Timout exceeded!"); }
}
}
Timeout = 1;
while (!IsFileReady(SourceFile))
{
System.Threading.Thread.Sleep(Timeout);
Timeout++;
if (Timeout == FileTimeout)
{
// todo
if (Debugger.IsAttached) { throw new Exception("Timout exceeded!"); }
}
}
}
static bool IsFileReady(String SourceFile)
{
try
{
using (FileStream inputStream = File.Open(SourceFile, FileMode.Open, FileAccess.Read, FileShare.None))
{
if (inputStream.Length > 0)
{
return true;
}
else
{
return false;
}
}
}
catch (Exception)
{
return false;
}
}
}
public struct Functions
{
public static string CleanXML(string Text)
{
Text = Text.Replace(#"&", #"&");
Text = Text.Replace(#"<", #"<");
Text = Text.Replace(#">", #">");
Text = Text.Replace(#"""", #""");
Text = Text.Replace(#"'", #"'");
return Text;
}
}
}
void Work(string Name)
{
_worker = _workers.FirstOrDefault(w => w.Name == Name);
if (_worker == null)
{
_worker = new worker(Name);
_worker.Feedback+=new worker.FeedbackHandler(Feedback);
_worker.Folder = Path.Combine(_queuefolder, Name);
_worker.Outfolder = _outfolder;
_worker.Backupfolder = _backupfolder;
_workers.Add(_worker);
Thread _thread = new Thread(_worker.Start);
_thread.Start();
_thread.Join();
}
}
To clarify what i meant:
//worker class
private volatile bool _stopping;
private Thread _thread;
public void Start()
{
_stopping = false;
Directory.CreateDirectory(_folder);
_thread = new Thread(Process);
_thread.Start();
Feedback(this, "[" + _name + "] started!");
}
public void Stop()
{
_stopping = true;
_thread.Join();
Feedback(this, "[" + _name + "] stopped...");
}
private void Process()
{
while(!_stopping)
{
......
Thread.Sleep(100);
}
}
Because the way you are using timers... It's wrong. And while its interesting to know, why windows locks the folder, you should start from doing some refactoring. It might actually solve your problem along the way.
I'm working on a network monitoring application, that pings a (not known) number of hosts. So far I have the code below. I've made a class PingHost with a function zping and I called it with the help of a timer once every 2 seconds to let the 2 pings to finish, even if one of them gets TimedOut. But I think a better solution is to generate a new thread for every ping, so that the ping of every host would be independent.
Can anyone give me a hint how to do this?
namespace pinguin
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void timer1_Tick(object sender, EventArgs e)
{
PingHost caca = new PingHost();
PingHost caca1 = new PingHost();
this.label1.Text = caca.zping("89.115.14.160");
this.label2.Text = caca1.zping("89.115.14.129");
}
}
public class PingHost
{
public string zping(string dest)
{
Application.DoEvents();
Ping sender = new Ping();
PingOptions options = new PingOptions();
options.DontFragment = true;
string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
byte[] buffer = Encoding.ASCII.GetBytes(data);
int timeout = 50;
int failed = 0;
int pingAmount = 5;
string stat = "";
PingReply reply = sender.Send(dest, timeout, buffer, options);
if (reply.Status == IPStatus.Success)
{
stat = "ok";
}
else
{
stat = "not ok!";
}
return stat;
}
}
}
If you use .NET 4 you can use Parallel.Invoke.
You could handle the Ping.PingCompleted event:
ping.PingCompleted += new PingCompletedEventHandler(ping_PingCompleted);
then use:
ping.SendAsync()
side note: Choose more suitable names for your classes and routines. PingHost is more suitable as a routine name
Once I wrote such a solution (it constantly pings about 300 machines):
public class ManyAdressPing {
private readonly bool bAutoStarted;
private readonly CancellationTokenSource cancel = new CancellationTokenSource();
public ConcurrentDictionary<IPAddress, OneAddressPing> pingi = new ConcurrentDictionary<IPAddress, OneAddressPing>();
public ManyAdressPing(bool AutoStarted = true) {
bAutoStarted = AutoStarted;
}
public int CountPings => pingi.Count;
public void AddPingAddress(IPAddress addr, int msTimeOut = 3000, int BetweenPing = 3000) {
var oap = new OneAddressPing(addr, cancel.Token, msTimeOut, BetweenPing);
if (bAutoStarted) oap.Start();
pingi.TryAdd(oap.ipAddress, oap);
}
public void RemovePingAddress(IPAddress addr) {
if (pingi.TryRemove(addr, out var p)) p.Stop();
}
public void Stop() {
cancel.Cancel();
foreach (var pair in pingi) pair.Value.Stop();
}
public PingReply GetReply(IPAddress addr) {
if (pingi.ContainsKey(addr)) return pingi[addr].GetReply();
return null;
}
public Tuple<long, long> GetSuccessOperation(IPAddress addr) {
if (pingi.ContainsKey(addr)) return pingi[addr].GetSuccessOperation();
return null;
}
public PingReply[] GetReply() {
PingReply[] ret = pingi.Values.Select(x=>x.GetReply()).ToArray();
return ret;
}
public PingInfo GetPingInfo(IPAddress addr) {
if (pingi.ContainsKey(addr)) {
var ret = new PingInfo();
var p = pingi[addr];
ret.reply = p.GetReply();
ret.SuccessPing = p._SuccessReply;
ret.FailPing = p._FailReply;
ret.LastSuccessPing = p.LastSuccessfullPing;
return ret;
}
return null;
}
public bool IsPinged(IPAddress addr) {
if (pingi.ContainsKey(addr)) return true;
return false;
}
public IPAddress[] GetAddressesPing() {
return pingi.Keys.ToArray();
}
}
public class PingInfo {
public PingReply reply;
public long SuccessPing = 0;
public long FailPing = 0;
public DateTime LastSuccessPing;
public override string ToString() {
return $"Sping: {SuccessPing} last={LastSuccessPing}, Fping:{FailPing}, reply:{reply}";
}
}
public class OneAddressPing {
public static byte[] bu = {
0
};
public long _FailReply;
public long _SuccessReply;
private bool bStop = false;
private readonly CancellationToken cancellationToken;
public DateTime LastSuccessfullPing = DateTime.MinValue;
public int mSecBetweenPing = 3000;
public Ping ping;
public PingOptions popt;
private Task pTask;
// Here is a self-written LIFO stack
public LightQueue<PingReply> replys = new LightQueue<PingReply>(10);
private readonly AutoResetEvent reset = new AutoResetEvent(false);
private Logger log = null;
private Task pinging = null;
public OneAddressPing(IPAddress addr, CancellationToken ct, int timeOut = 3000, int BetweenPing = 3000, Logger _log =null) {
ipAddress = addr;
popt = new PingOptions();
popt.DontFragment = false;
cancellationToken = ct;
mSecTimeOut = timeOut;
mSecBetweenPing = BetweenPing;
log = _log;
}
public int mSecTimeOut { get; set; } = 3000;
public IPAddress ipAddress { get; set; }
public int CountPings => replys.Length;
private void SetReply(PingReply rep) {
if (rep == null) return;
replys.Put(rep);
if (rep.Status == IPStatus.Success) {
Interlocked.Increment(ref _SuccessReply);
LastSuccessfullPing = DateTime.Now;
} else {
Interlocked.Increment(ref _FailReply);
}
}
public async Task Start() {
if (pTask == null || pTask.Status != TaskStatus.Running) {
ping = new Ping();
Task.Factory.StartNew(PingCircle, TaskCreationOptions.RunContinuationsAsynchronously | TaskCreationOptions.LongRunning); pTask = Task.Run(PingCircle, cancellationToken);
}
}
public void Stop() {
if (pTask.Status == TaskStatus.Running) {
bStop = true;
try {
pTask.Wait(mSecTimeOut, cancellationToken);
} catch (Exception ex) {
log.ErrorSource($"Error ping stop: {ex.Message}");
}
}
}
private async Task PingCircle() {
while (cancellationToken.IsCancellationRequested == false && !bStop) {
try {
try {
PingReply rep = await ping.SendPingAsync(ipAddress, mSecTimeOut, bu,popt);
if (rep != null) SetReply(rep);
} catch (PingException p) {
// ignore ping error
Debug.WriteLine($"error: {p}");
} catch (Exception ee) {
log?.ErrorSource(ee);
Debug.WriteLine($"error: {ee}");
}
await Task.Delay(mSecBetweenPing, cancellationToken);
} catch (Exception ee) {
log?.ErrorSource(ee);
}
}
}
public PingReply GetReply() {
if (replys.IsEmpty) return null;
return replys.PeekLast(0);
}
public Tuple<long, long> GetSuccessOperation() {
return new Tuple<long, long>(_SuccessReply, _FailReply);
}
public bool LongPingSuccess() {
int ret = 0;
for (int i = 0; i < 5; i++) {
var r = replys.PeekLast(i);
if (r.Status == IPStatus.Success) ret++;
}
if (ret > 2) return true;
return false;
}
}