צריך עזרה עם ManualResetEvent ב-C# - תכנות - HWzone פורומים
עבור לתוכן
  • צור חשבון

צריך עזרה עם ManualResetEvent ב-C#


moskitos

Recommended Posts

יש לי אובייקט מסויים שאני רוצה לבדוק את אחד הפרופרטי שלו וכשהוא מתחלף ל-false בעקבות לחיצה על כפתור מסויים אני רוצה שיהיה לי כמו thread.sleep ז"א שהוא יסתובב סביב עצמו ויבדוק מתי הוא שוב יהיה true ואז ימשיך, קראתי קצת והסתכלתי על ManualResetEvent אבל לא ממש הצלחתי לעשות מה שאני רוצה, אשמח לעזרה.

עריכה:

יצרתי אובייקט:

ManualResetEvent mre = new ManualResetEvent(false);

ועשיתי תנאי שאם הפרופרטי של האובייקט שלי הוא true אז mre.WaitOne ואז הריצה שלי ב-pause, עכשיו ב-else אני לא יודע מה לשים ככה שהם אותו הפרופרטי שלי משתנה ל-false בחזרה הריצה ממשיכה, ניסיתי set או reset אבל זה לא עבד.

קישור לתוכן
שתף באתרים אחרים

מה? לא ממש ברור מהתיאור שלך מה אתה עושה או רוצה לעשות.

תוכל להעלות קטע קוד רלוונטי, או לפחות לנסות להסביר את עצמך יותר טוב?

קריאה ל-mre.WaitOne סה"כ בודקת אם ה-Event הוא במצב Set, ואם לא אז היא מחכה עד שהוא מגיע למצב הזה (כלומר מישהו עושה mre.Set).

קישור לתוכן
שתף באתרים אחרים

זה מהפרוייקט של Pcapdot שמנגן פקטות לכרטיס רשת.

הקוד שלי משתמש בו וממש איך שהוא מנגן את הפקטות (סימנתי את זה ב-$$$$ ממש לפני סוף הקוד) יש לי אובייקט שיושב לפני השורה הזו ואם אני לוחץ על כפתור מסויים הפרופרטי שלו הופך ל-true ואז עשיתי לו WaitOne והוא באמת ב-pause ואז אני רוצה שאם אני שוב לוחץ על הכפתור בתוכנה והפרופרטי הופך ל-false התוכנה ממשיכה, כרגע היא עוצרת כמו שאני רוצה אבל לא ממשיכה


using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using PcapDotNet.Core;
using PcapDotNet.Packets;


namespace SendingPacketsUsingSendBuffer
{
class Program
{
static void Main(string[] args)
{
// Send anonymous statistics about the usage of Pcap.Net
PcapDotNet.Analysis.PcapDotNetAnalysis.OptIn = true;


// Check the validity of the command line
if (args.Length == 0 || args.Length > 2)
{
Usage();
return;
}


// Retrieve the device list from the local machine
IList<LivePacketDevice> allDevices = LivePacketDevice.AllLocalMachine;


if (allDevices.Count == 0)
{
Console.WriteLine("No interfaces found! Make sure WinPcap is installed.");
return;
}


// Print the list
for (int i = 0; i != allDevices.Count; ++i)
{
LivePacketDevice device = allDevices[i];
Console.Write((i + 1) + ". " + device.Name);
if (device.Description != null)
Console.WriteLine(" (" + device.Description + ")");
else
Console.WriteLine(" (No description available)");
}


int deviceIndex = 0;
do
{
Console.WriteLine("Enter the interface number (1-" + allDevices.Count + "):");
string deviceIndexString = Console.ReadLine();
if (!int.TryParse(deviceIndexString, out deviceIndex) ||
deviceIndex < 1 || deviceIndex > allDevices.Count)
{
deviceIndex = 0;
}
} while (deviceIndex == 0);


// Take the selected adapter
PacketDevice selectedOutputDevice = allDevices[deviceIndex - 1];


// Retrieve the length of the capture file
long capLength = new FileInfo(args[0]).Length;


// Chek if the timestamps must be respected
bool isSync = (args.Length == 2 && args[1][0] == 's');


// Open the capture file
OfflinePacketDevice selectedInputDevice = new OfflinePacketDevice(args[0]);


using (PacketCommunicator inputCommunicator =
selectedInputDevice.Open(65536, // portion of the packet to capture
// 65536 guarantees that the whole packet will be captured on all the link layers
PacketDeviceOpenAttributes.Promiscuous, // promiscuous mode
1000)) // read timeout
{
using (PacketCommunicator outputCommunicator =
selectedOutputDevice.Open(100, PacketDeviceOpenAttributes.Promiscuous, 1000))
{
// Check the type
if (inputCommunicator.DataLink != outputCommunicator.DataLink)
{
Console.WriteLine(
"Warning: the datalink of the capture differs from the one of the selected interface.");
Console.WriteLine("Press a key to continue, or CTRL+C to stop.");
Console.ReadKey();
}


// Allocate a send buffer
using (PacketSendBuffer sendBuffer = new PacketSendBuffer((uint)capLength))
{
// Fill the buffer with the packets from the file
int numPackets = 0;
Packet packet;
while (inputCommunicator.ReceivePacket(out packet) == PacketCommunicatorReceiveResult.Ok)
{
sendBuffer.Enqueue(packet);
++numPackets;
}

פה יושב איזה אובייקט שלי שיש לו פרופרטי שמשתנה מ-false ל-true אם אני לוחץ על כפתור pause בתוכנה

// Transmit the queue
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
long startTimeMs = stopwatch.ElapsedMilliseconds;
Console.WriteLine("Start Time: " + startTimeMs);
outputCommunicator.Transmit(sendBuffer, isSync); $$$$$
}
}
}
}

}
}
}

קישור לתוכן
שתף באתרים אחרים

אז אתה צריך שבלחיצת הכפתור יתבצע משהו כזה:

if (paused)
{
mre.Set();
paused = false;
}
else
{
mre.Reset();
paused = true;
}

ככה בפעם הראשונה שלוחצים על הכפתור הוא ידאג שה-mre יהיה כבוי (ומי שעושה mre.WaitOne אכן יחכה). בפעם השנייה שלוחצים על הכפתור זה ישחרר את ה-mre (כלומר יעשה mre.Set).

קישור לתוכן
שתף באתרים אחרים

כן, מי שקורא ל-WaitOne מחכה. כמובן, בשביל לשחרר אותו צריך שת'רד אחר יקרא ל-Set.

ManualResetEvent הוא אובייקט מאוד מאוד פשוט, עם שלוש פונקציות עיקריות - Set, Reset ו-WaitOne.

הפונקציות Set ו-Reset פשוט משנות את המצב שלו בין "דלוק" ו"כבוי" (Set מדליקה, Reset מכבה).

הפונקציה WaitOne אומרת כזה דברים: אם האובייקט כבוי, אל תעשה כלום (כלומר הת'רד ממשיך לרוץ כרגיל). אחרת, חכה עד שהאובייקט יהיה דלוק (כלומר, תשהה את הת'רד הנוכחי עד שמישהו יעשה Set לאובייקט).

במאורע שמטפל בלחיצה על כפתור ה-pause צריך לשים את הקוד שרשמתי קודם.

בפונקציה שאתה רוצה שתהיה מסוגלת לעצור, אתה צריך לעשות mre.WaitOne. בכל מקום שבו אתה רוצה שהפונקציה תעצור (אם צריך), אתה יכול להוסיף קריאה ל-mre.WaitOne. ייתכן שצריך לקרוא לפונקציה הזו כמה פעמים במהלך הפונקציה, כדי לוודא שהיא תעצור גם אם מישהו לחץ על pause בזמן שהפונקציה רצה.

קישור לתוכן
שתף באתרים אחרים

אם כשאני מתחיל את הריצה של התוכנית אני עושה לאובייטק SET הוא נופל על Object reference not set to an instance of an object ואני לא מבין למה.

אם אני לא עושה לא את זה וולחיצת כפתור דואג שהאובייטק ישתנה ל-WaitOne הוא נופל על אותה השגיאה.

קישור לתוכן
שתף באתרים אחרים


if (IsPause== true)
{
mManualRe.Reset();
IsPause= true;
}


if (IsPause== false)
{
mManualRe.Set();
IsPause= false;
}

זה מה שעשיתי:

כשיצרתי את האובייקט עשיתי לו SET (האובייקט הוא mManualRe), עכשיו המשתנה IsPause אומר אם לחצתי על כפתור ה-Pause, אם הוא True הייתה לחיצה והתוכמה אמורה לעצור ולחיצה נוספת הופכת את המשתנה ל-False והתוכנה אמורה להמשיך.

כרגע זה לא עובד לי לפי מה שכתבת לי

קישור לתוכן
שתף באתרים אחרים

ארכיון

דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.

×
  • צור חדש...