标签: beginread

使用FileStream.ReadAsync()时,我应该以异步模式打开文件吗?

执行异步I/O的旧.Net方式FileStream是使用FileStream.BeginRead()FileStream.EndRead().

状态的MSDN文档FileStream.BeginRead():

FileStream提供两种不同的操作模式:同步I/O和异步I/O. 虽然可以使用其中任何一种,但底层操作系统资源可能仅允许以这些模式之一进行访问.

默认情况下,FileStream会同步打开操作系统句柄.在Windows中,这会降低异步方法的速度.如果使用异步方法,请使用FileStream(String,FileMode,FileAccess,FileShare,Int32,Boolean)构造函数.

.Net 4.5x对执行异步I/O的方式FileStream是使用Stream.ReadAsync().

MSDN文档FileStream.ReadAsync()直接链接到文档的链接Stream.ReadAsync().本文档未提及在异步模式下打开文件的任何需要; 实际上,文档中的示例代码显然没有这样做.

因此,我假设在使用时File.ReadAsync()不需要以异步模式打开文件.

这个假设是否正确?

[编辑]

我刚刚发现了一篇关于使用Async for File Access的MSDN文章.

这表明:

本主题中的示例使用FileStream类,该类具有导致在操作系统级别发生异步I/O的选项.通过使用此选项,您可以避免在许多情况下阻止ThreadPool线程.

要启用此选项,请在构造函数调用中指定useAsync = true或options = FileOptions.Asynchronous参数.

所以,现在我在想,我应该可以打开该文件在异步模式......如果是这样,这是有点遗憾的是,在文档中提供的示例代码ReadAsync()不能打开该文件异步!

c# filestream beginread async-await

16
推荐指数
1
解决办法
2243
查看次数

BeginReceive/BeginRead超时

我正在使用NetworkStream和TcpClient使用BeginRead异步接收数据.我需要对此操作应用超时,以便在指定的时间后读取将被中止.

据我所知,NetworkStream或TcpClient不支持 - 有一个ReceiveTimeout属性,但这似乎只适用于同步等效 - 'Read'.

甚至底层的Socket类似乎也不支持其BeginReceive方法中的超时.

我已经搜索过这个问题,我看到的唯一建议的解决方案是设置另一个后台线程来取消操作,如果它在超时期限内没有完成.这看起来像是一个可怕的黑客.当然有更好的方法吗?

asynchronous networkstream tcpclient beginread beginreceive

15
推荐指数
1
解决办法
1万
查看次数

在AsyncCallback函数之外停止异步流

我有一个Stream对象,我正在使用BeginRead开始(显然)读入缓冲区; 一旦读取完成,就会调用AsyncCallback函数.在这个函数中,我可以检查用户是否想要获取下一个"块"并再次启动BeginRead过程.

我遇到的问题是用户可能会选择在流仍在读取时取消(因此在调用AsyncCallback函数之前),那么如何取消流的读取?

只是为了进一步解释这个问题 - 如果我使用带有Streams Read方法或异步BeginRead方法的BackgroundWorker,我似乎会得到相同的结果.在我可以检查流是否应该停止读取之前,用户可以等待Read/BeginRead方法完成任何时间长度.

编辑:下面的代码应该可以完成这项任务,我距离C#中的任何一个距离都是一百万英里所以它可能会有一些错误,因为我怀疑它是完美的,尽管它确实展示了解决方案.

简而言之,CWorkManager管理一定数量的线程(保存在CWorkerDetail类中).每个CWorkerDetail都有一个状态,可以是EWaiting意味着工作人员可以启动,EReading意味着工作人员正在从源读取,在此期间工作人员可以立即停止,EWriting可以保存读取到磁盘的数据 - 这不能立即停止,这个过程必须在线程停止之前完成.最后是EAborting,由经理设定,如果工人应该尽快中止; 现在只有在工作者处于无法中断的事物(例如写入磁盘)的中间时才会设置此项.

现在,实际上没有任何读取或写入,因为这会使主要解决方案复杂化(这基本上只是StopWorker函数检查CWorker的标志,看它是否可以立即中止); 因此我们只是让线程睡觉.

GUI侧非常简单,只有一个列表框(显示每个工作人员的状态)和一个停止和启动按钮.所有代码都在下面,希望这有助于某些人,但正如我所说,我对C#并不擅长,所以请注意bug等...

CWorkManager.cs:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;


namespace ThreadApplication {


    //A worker that spawns a number of threads (managed internally) that does nothing useful at all.
    public class CWorkManager {


        //The status of the worker.
        public enum EWorkerStatus {
            EWaiting,
            EReading,
            EWriting,
            EAborting,
        }


        //Holds all data relevant to the worker.
        private class CWorkerDetails {

            //Simple variables.
            private readonly Object _Lock=new Object(); …
Run Code Online (Sandbox Code Playgroud)

c# stream beginread

5
推荐指数
1
解决办法
2950
查看次数

停止 Stream.BeginRead()

我需要从我的虚拟 com 端口读取数据并检测消息“Dreq”。一旦我按下连接按钮,它就会连接到我的 COM8 端口并开始读取新线程。我还有一个断开连接按钮,我希望在其中关闭读数并断开与 COM8 端口的连接。但是,我在关闭 BeginRead 时遇到问题。

public partial class Form1 : Form
{
    SerialPort sp;
    Stream stream;
    IAsyncResult recv_result;

    private void button1_Click(object sender, EventArgs e)
    {
        sp = new SerialPort("COM8", 9600);
        sp.Open();
        sp.ReadTimeout = 50000;
        sp.NewLine = "\n\r\0";
        stream = sp.BaseStream;
        recv_result = stream.BeginRead(new byte[1], 0, 0, new 
                                       AsyncCallback(ReadCallBack), stream);
    }

    private void ReadCallBack(IAsyncResult ar)
    {            
        Stream stream = (Stream)ar.AsyncState;
        string temp;

        while (stream.CanRead)
        {
            temp = sp.ReadLine();                
            // ... do something with temp
        }
    }

    private …
Run Code Online (Sandbox Code Playgroud)

c# stream beginread

5
推荐指数
1
解决办法
7666
查看次数

FileOptions.Asynchronous 导致 FileStream.BeginRead 阻塞

为什么使用 FileOptions.Asynchronous 创建 FileStream 会导致 FileStream.BeginRead 阻塞调用线程?

这是代码片段:

private static Task<int> ReadFileAsync(string filePath)
  {
     var file = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite, 64 * 1024, FileOptions.Asynchronous);
     FileInfo fi = new FileInfo(filePath);
     byte[] buffer = new byte[fi.Length];
     Task<int> task = Task<int>.Factory.FromAsync(file.BeginRead, file.EndRead, buffer, 0, buffer.Length, null);         
     return task.ContinueWith(t =>
     {
        file.Close();
        Console.WriteLine("Done ReadFileAsync, read " + t.Result + " bytes.");
        return t.Result;
     });
  }
Run Code Online (Sandbox Code Playgroud)

当使用 JetBrains dotPeek 深入研究 MSFT FileStream 代码时,他们的代码中似乎存在一个错误:

      if (!this._isAsync)
    return base.BeginRead(array, offset, numBytes, userCallback, stateObject);
  else
    return …
Run Code Online (Sandbox Code Playgroud)

.net c# asynchronous filestream beginread

5
推荐指数
1
解决办法
5023
查看次数

TcpClient; NetworkStream; ReadAsync; C#

请原谅我对任务和异步的知识不足。

使用TcpClient类,我正在与可用服务器建立连接:

void async RunClientAsync()
{
    TcpClient client = new TcpClient();
    try
    {
        await client.ConnectAsync(IPAddress.Parse("1.1.1.1"), 8889);
        Task.Start(() => ReadClientAsync(client));
    }
    catch (Exception ex)
    {
        HandleException(ex);
    }
}

// -----

void async ReadClientAsync(TcpClient client)
{
    byte[] bf = new byte[2048];
    try
    {
        while(true)
        {
            int br = await client.NetworkStream().ReadAsync();
            if (br > 0) 
            {
                HandleInboundData(bf, br);
            }
        }
    }
    catch (Exception ex)
    {
        HandleException(ex);
    }
}
Run Code Online (Sandbox Code Playgroud)

辅助方法HandleException(Exception ex)和HandleInboundData(byte [] buffer,int length)将执行假定的任务。

与服务器的连接将是永久的,并且从服务器接收的数据的长度和频率将是未知的,其想法是将任务丢在那里,仅在数据可用时才接收和处理入站数据。

ReadClientAsync(TcpClient client)显然是失败的,因为如果没有可用数据,ReadAsync将始终返回0字节。

我应该如何使用异步/任务来编写ReadClientAsync来防止出现繁忙循环的情况?我以前在这些情况下使用BeginRead / EndRead,效果很好。在这种特殊情况下,这将是解决方案吗?

谢谢,

c# tcpclient beginread

3
推荐指数
1
解决办法
1万
查看次数

C#网络流碎片数据

我的背景

我有一个TCP网络程序,它通过连接发送已经序列化并编码到base64的大对象.我写了一个客户端库和一个服务器库,他们都使用NetworkStream's Begin/EndReadBegin/EndWrite.这是我正在使用的代码(非常简化的版本):

对于服务器:

var Server = new TcpServer(/* network stuffs */);
Server.Connect();
Server.OnClientConnect += new ClientConnectEventHandler(Server_OnClientConnect);

void Server_OnClientConnect()
{
    LargeObject obj = CalculateLotsOfBoringStuff();
    Server.Write(obj.SerializeAndEncodeBase64());
}
Run Code Online (Sandbox Code Playgroud)

然后客户:

var Client = new TcpClient(/* more network stuffs */);
Client.Connect();
Client.OnMessageFromServer += new MessageEventHandler(Client_OnMessageFromServer);

void Client_OnMessageFromServer(MessageEventArgs mea)
{
    DoSomethingWithLargeObject(mea.Data.DecodeBase64AndDeserialize());
}
Run Code Online (Sandbox Code Playgroud)

客户端库有一个回调方法,NetworkStream.BeginRead用于触发OnMessageFromServer将数据作为字符串传递的事件MessageEventArgs.

我的问题

BeginRead/EndRead但是,当通过它接收大量数据时,它似乎在多个消息上分散.EG假装这是一条很长的信息:

"This is a really long message except not because it's for explanatory purposes."
Run Code Online (Sandbox Code Playgroud)

如果这确实是一个很长的消息,Client_OnMessageFromServer可能会被称为...说"三条消息"的碎片部分:

"This is a …
Run Code Online (Sandbox Code Playgroud)

c# networkstream fragment beginread

0
推荐指数
1
解决办法
1349
查看次数

在C#中读取整数的替代方法

我知道通过使用Convert.To方法读取输入,但除此之外还有什么方法可以阅读.

int k = Convert.ToInt16(Console.ReadLine()); 
Run Code Online (Sandbox Code Playgroud)

c# inputstream input type-conversion beginread

-3
推荐指数
1
解决办法
630
查看次数