Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/257.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在主线程C的睡眠模式期间处理从事件处理程序发送的数据#_C#_Multithreading_Serial Port - Fatal编程技术网

C# 在主线程C的睡眠模式期间处理从事件处理程序发送的数据#

C# 在主线程C的睡眠模式期间处理从事件处理程序发送的数据#,c#,multithreading,serial-port,C#,Multithreading,Serial Port,假设我在C#中有一个事件侦听器,它等待来自串行端口的数据,这些数据在通过设置某些状态捕获后返回。在主循环中,我查看该状态,并根据该状态决定下一步要做什么 为此,我首先将命令写入串行端口,并使用Thread.Sleep方法等待输出。当主线程仍处于睡眠模式时,事件侦听器将已经发送数据,并且没有任何操作来处理该场景 有谁能告诉我这种情况下会有什么后果以及如何预防 代码是这样的 bool status = false; //main thread private void Main() {

假设我在C#中有一个事件侦听器,它等待来自串行端口的数据,这些数据在通过设置某些状态捕获后返回。在主循环中,我查看该状态,并根据该状态决定下一步要做什么

为此,我首先将命令写入串行端口,并使用Thread.Sleep方法等待输出。当主线程仍处于睡眠模式时,事件侦听器将已经发送数据,并且没有任何操作来处理该场景

有谁能告诉我这种情况下会有什么后果以及如何预防

代码是这样的

 bool status = false;
//main thread
private void Main()
{

    //some Code
    serialPort.Write("something");

    //Wait for 10 sec
    Thread.Sleep(10000);
    while(status == false)
    {
        // do something else
     }
}


   //Ignore the syntax, this is just to make people understand
   public void OndataReceived(object sender, EventArg arg)
   {
       //Function that recieve the data
       Receive();

       //change status to true
       status = true;

       return;
   }

这个问题措辞笨拙,但如果我理解正确的话,您是在问,如果数据接收时间早于10秒,如何避免等待10秒

可以使用较旧的同步对象,例如
WaitHandle
子类之一、
Monitor
,甚至是信号量。但是对于这种类型的场景,当前的C#习惯用法是使用
TaskCompletionSource
,它提供了一个可等待的对象和同时返回结果值的选项

例如:

TaskCompletionSource<bool> _result;

//main thread
private void Main()
{

    //some Code
    serialPort.Write("something");

    _result = new TaskCompletionSource<bool>();

    // Normally, one should "await" a Task. But in the Main() method, which
    // cannot be "async", we have to just wait synchronously.
    Task completed = Task.WhenAny(_result.Task,
        Task.Delay(TimeSpan.FromSeconds(10)).Result;

    // Don't check "_result.Result" unless the task has completed,
    // because otherwise the thread will block. If it is completed,
    // check "_result.Result" as the equivalent to examining the "status"
    // variable in the previous code example.
    while(!_result.IsCompleted || !_result.Result)
    {
        // do something else
    }
}

public void OndataReceived(object sender, EventArg arg)
{
    //Function that recieve the data
    Receive();

    //change status to true
    _result.SetResult(true);

    return;
}
TaskCompletionSource\u结果;
//主线
私有void Main()
{
//一些代码
serialPort.Write(“某物”);
_结果=新任务完成源();
//通常,应该“等待”任务
//不能“异步”,我们只能同步等待。
Task completed=Task.Wheny(_result.Task,
任务延迟(时间跨度从秒(10))。结果;
//除非任务已完成,否则不要选中“\u result.result”,
//因为否则线程会阻塞。如果它完成,
//检查“_result.result”等同于检查“status”
//前面代码示例中的变量。
而(!_result.IsCompleted | |!_result.result)
{
//做点别的
}
}
公共无效OndataReceived(对象发送方,事件参数)
{
//接收数据的函数
接收();
//将状态更改为true
_result.SetResult(true);
返回;
}

这个问题措辞笨拙,但如果我理解正确,您会问,如果数据接收时间早于10秒,如何避免等待10秒

可以使用较旧的同步对象,例如
WaitHandle
子类之一、
Monitor
,甚至是信号量。但对于这种类型的场景,当前的C习惯用法是使用
TaskCompletionSource
,它同时提供可等待对象和返回结果值的选项。

例如:

TaskCompletionSource<bool> _result;

//main thread
private void Main()
{

    //some Code
    serialPort.Write("something");

    _result = new TaskCompletionSource<bool>();

    // Normally, one should "await" a Task. But in the Main() method, which
    // cannot be "async", we have to just wait synchronously.
    Task completed = Task.WhenAny(_result.Task,
        Task.Delay(TimeSpan.FromSeconds(10)).Result;

    // Don't check "_result.Result" unless the task has completed,
    // because otherwise the thread will block. If it is completed,
    // check "_result.Result" as the equivalent to examining the "status"
    // variable in the previous code example.
    while(!_result.IsCompleted || !_result.Result)
    {
        // do something else
    }
}

public void OndataReceived(object sender, EventArg arg)
{
    //Function that recieve the data
    Receive();

    //change status to true
    _result.SetResult(true);

    return;
}
TaskCompletionSource\u结果;
//主线
私有void Main()
{
//一些代码
serialPort.Write(“某物”);
_结果=新任务完成源();
//通常,应该“等待”任务
//不能“异步”,我们只能同步等待。
Task completed=Task.Wheny(_result.Task,
任务延迟(时间跨度从秒(10))。结果;
//除非任务已完成,否则不要选中“\u result.result”,
//因为否则线程会阻塞。如果它完成,
//检查“_result.result”等同于检查“status”
//前面代码示例中的变量。
而(!_result.IsCompleted | |!_result.result)
{
//做点别的
}
}
公共无效OndataReceived(对象发送方,事件参数)
{
//接收数据的函数
接收();
//将状态更改为true
_result.SetResult(true);
返回;
}

您真正需要的是独立的线程、状态机和委托(回调)。我在这里写了一个不错的示例:

您真正需要的是独立的线程、状态机和委托(回调)。我在这里写了一个不错的例子:

看看手动和自动reseteventcreate自定义事件,从
OndataReceived
方法内部启动它,然后在我看来的方法中执行下一步:看看手动和自动reseteventcreate自定义事件,从
OndataReceived
方法内部启动它,然后执行以下操作:我的观点中方法的下一步是Tanks Peter。是的,我想说同样的话。但是在我的例子中,如果数据是在主线程发送时发送的,这是通过执行thread.Start(main)启动的,处于睡眠模式,整个windows服务都会挂起,因此您的回答可能会对我有所帮助。还有一件事,我有很多地方使用线程。使用睡眠时,使用新任务对象是否安全?“我有很多地方使用线程。使用睡眠时,使用新任务对象是否安全?”--无论在哪里,只要有
Thread.Sleep()
,您都应该寻找替代实现(如上面所述)。
Thread.Sleep()
方法从来都不是延迟处理的好方法,因为它阻塞了调用它的线程,而现代C#有更好的/有用的方法来实现相同的结果。谢谢Peter。是的,我想说同样的话。但是在我的情况下,如果数据是在主线程发送时发送的,则通过执行thread.Start(main)启动主线程,处于睡眠模式,整个windows服务都会挂起,因此您的回答可能会对我有所帮助。还有一件事,我有很多地方使用线程。使用睡眠时,使用新任务对象是否安全?“我有很多地方使用线程。使用睡眠时,使用新任务对象是否安全?”--无论您在哪里使用
Thread.Sleep()
,您都应该寻找替代实现(如上面所述)。
Thread.Sleep()
方法从来都不是延迟处理的好方法,因为它会阻塞调用它的线程,而现代C#有更好/有用的方法来实现相同的结果。