2012-08-02 13 views
8

क्या एसिंक्रोनस फ़ंक्शन लिखने का कोई तरीका है जो फ़ाइल को बार-बार फ़ाइल में लिखता है। ': \ अस्थायी \ data.txt सी' क्योंकि इसे किसी अन्य प्रक्रियाफ़ाइल को अतुल्यकालिक रूप से लिखना

public void GoButton_Click(object sender, System.EventArgs e) 
{ 
    IAsyncResult ar = DoSomethingAsync(strURL, strInput); 
    Session["result"] = ar; 
    Response.Redirect("wait1.aspx"); 
} 

private IAsyncResult DoSomethingAsync(string strURL, string strInput) 
{ 
    DoSomethingDelegate doSomethingDelegate = new DoSomethingDelegate(DoSomething); 
    IAsyncResult ar = doSomethingDelegate.BeginInvoke(strURL, strInput, new AsyncCallback(MyCallback), null); 
    return ar; 
} 

private delegate void DoSomethingDelegate(string strURL, string strInput); 

private void MyCallback(IAsyncResult ar) 
{ 
    AsyncResult aResult = (AsyncResult)ar; 
    DoSomethingDelegate doSomethingDelegate = (DoSomethingDelegate)aResult.AsyncDelegate; 
    doSomethingDelegate.EndInvoke(ar); 
} 

private void DoSomething(string strURL, string strInput) 
{ 
    int i = 0; 
    for (i = 0; i < 1000; i++) 
    { 
     m_streamWriter.BaseStream.Seek(0, SeekOrigin.End); 
     m_streamWriter.WriteLine("{0} ", MethodCall(strURL, strInput)); 
     m_streamWriter.Flush(); 
     m_streamWriter.Close(); 
    } 
} 
+0

हाँ, यह संभव है। सुनिश्चित करें कि आप मुख्य धागे में फ़ाइल नहीं खोलते हैं और किसी अन्य का उपयोग करके संशोधित नहीं करते हैं। – Leri

+0

मुझे कोड –

+0

को संशोधित करना चाहिए यदि आप एक स्ट्रीम खोलते हैं तो अपवाद आमतौर पर होता है। दिए गए कोड उदाहरण के भीतर आप केवल एक मौजूदा स्ट्रीम को लिखते हैं, लेकिन वह कोड जहां आप स्ट्रीम बनाते हैं (और अपवाद फेंक दिया जाएगा) गायब है। – Oliver

उत्तर

11

ठीक है मुझे एक ही समस्या थी। और अब इसे हल किया। यह देर से सुझाव है लेकिन दूसरों के लिए मदद कर सकता है।

नीचे दिए गए कंसोल उदाहरणों में निम्नलिखित कथन का उपयोग शामिल करें। नीचे

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Text; 
using System.Threading.Tasks; 
Use of the FileStream Class 

उदाहरण FileStream वर्ग है, जो एक विकल्प है कि कारण बनता है अतुल्यकालिक मैं/हे ऑपरेटिंग सिस्टम स्तर पर होते हैं के लिए है का उपयोग करें। कई मामलों में, यह थ्रेडपूल थ्रेड को अवरुद्ध करने से बच जाएगा। इस विकल्प को सक्षम करने के लिए, आपको कन्स्ट्रक्टर कॉल में उपयोग Async = true या options = FileOptions.Asynchronous तर्क निर्दिष्ट करना होगा।

StreamReader और StreamWriter में यह विकल्प नहीं है यदि आप उन्हें फ़ाइल पथ निर्दिष्ट करके सीधे खोलते हैं। StreamReader/Writer के पास यह विकल्प होता है यदि आप उन्हें स्ट्रीम स्ट्रीम प्रदान करते हैं जो फ़ाइलस्ट्रीम क्लास द्वारा खोला गया था। ध्यान दें कि एसिंक्रॉमी यूआई ऐप्स में एक प्रतिक्रियात्मक लाभ प्रदान करता है भले ही थ्रेड पूल थ्रेड अवरुद्ध हो, क्योंकि यूआई थ्रेड प्रतीक्षा के दौरान अवरुद्ध नहीं है।

लेखन पाठ

निम्न उदाहरण एक फ़ाइल में पाठ लिखता है। प्रत्येक प्रतीक्षा कथन पर, विधि तुरंत बाहर निकलती है। जब फ़ाइल I/O पूर्ण हो जाती है, तो प्रतीक्षा प्रतीक्षा विवरण के बाद विधि कथन पर फिर से शुरू होती है। ध्यान दें कि async संशोधक विधियों की परिभाषा में है जो प्रतीक्षा कथन का उपयोग करते हैं।

static void Main(string[] args) 
{ 
    ProcessWrite().Wait(); 
    Console.Write("Done "); 
    Console.ReadKey(); 
} 

static Task ProcessWrite() 
{ 
    string filePath = @"c:\temp2\temp2.txt"; 
    string text = "Hello World\r\n"; 

    return WriteTextAsync(filePath, text); 
} 

static async Task WriteTextAsync(string filePath, string text) 
{ 
    byte[] encodedText = Encoding.Unicode.GetBytes(text); 

    using (FileStream sourceStream = new FileStream(filePath, 
     FileMode.Append, FileAccess.Write, FileShare.None, 
     bufferSize: 4096, useAsync: true)) 
    { 
     await sourceStream.WriteAsync(encodedText, 0, encodedText.Length); 
    }; 
} 

पाठ

निम्न उदाहरण पढ़ना एक फ़ाइल से पाठ पढ़ता है। पाठ buffered है और, इस मामले में, एक स्ट्रिंगबिल्डर में रखा गया है। पिछले उदाहरण के विपरीत, प्रतीक्षा का मूल्यांकन एक मूल्य पैदा करता है। ReadAsync विधि देता है एक टास्क, तो इंतजार है मूल्यांकन कोई Int32 मूल्य (numRead) उसके बाद आपरेशन पूरा करता दिया जाता है पैदा करता है ..

static void Main(string[] args) 
{ 
    ProcessRead().Wait(); 
    Console.Write("Done "); 
    Console.ReadKey(); 
} 

static async Task ProcessRead() 
{ 
    string filePath = @"c:\temp2\temp2.txt"; 

    if (File.Exists(filePath) == false) 
    { 
     Console.WriteLine("file not found: " + filePath); 
    } 
    else { 
     try { 
      string text = await ReadTextAsync(filePath); 
      Console.WriteLine(text); 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine(ex.Message); 
     } 
    } 
} 

static async Task<string> ReadTextAsync(string filePath) 
{ 
    using (FileStream sourceStream = new FileStream(filePath, 
     FileMode.Open, FileAccess.Read, FileShare.Read, 
     bufferSize: 4096, useAsync: true)) 
    { 
     StringBuilder sb = new StringBuilder(); 

     byte[] buffer = new byte[0x1000]; 
     int numRead; 
     while ((numRead = await sourceStream.ReadAsync(buffer, 0, buffer.Length)) != 0) 
     { 
      string text = Encoding.Unicode.GetString(buffer, 0, numRead); 
      sb.Append(text); 
     } 

     return sb.ToString(); 
    } 
} 

आप से Using Async for File Access

आशा एक देखने के मूल स्रोत ले जा सकते हैं जो मदद करता है ...

+0

हालांकि यह लिंक प्रश्न का उत्तर दे सकता है, लेकिन यहां उत्तर के आवश्यक हिस्सों को शामिल करना बेहतर है और संदर्भ के लिए लिंक प्रदान करना बेहतर है। लिंक किए गए पृष्ठ में परिवर्तन होने पर लिंक-केवल उत्तर अमान्य हो सकते हैं। – StarsSky

+1

@StarsSky: आप सही हैं, यह पूरी तरह से समझ में आता है। मैं इसे संपादित कर दूंगा। सुझाव – curiousBoy

+3

के लिए धन्यवाद उत्तर में अब इसका समाधान है। – curiousBoy

4

द्वारा किया जा रहा है

मैं निम्न त्रुटि हो रही है जब मैं अतुल्यकालिक समारोह

प्रक्रिया फ़ाइल तक नहीं पहुँच सकते हैं बारे में फ़ाइल में असीमित रूप से लिखना इस मुद्दे को हल नहीं करेगा। आपको फ़ाइल उपलब्ध होने की प्रतीक्षा करनी होगी।

0

आखिरकार यह निर्भर करता है कि आप इसे करने का प्रयास क्यों कर रहे हैं।

यदि आप फ़ाइल में बहुत अधिक डेटा लिखने वाले नहीं हैं, तो आप लगातार इसे खोल और बंद कर सकते हैं।

वैकल्पिक रूप से, यदि आप जानते हैं कि जब आप फ़ाइल खोलना चाहते हैं और जब आप इसे बंद करना चाहते हैं, तो इसे खोलने पर आप इसे खोल सकते हैं, फिर इसे तब तक लिखने के लिए खोलें जब तक आपको पता न हो कि अब इसकी आवश्यकता नहीं है।

+0

पर सामग्री लिख रहा हूं, मैं वेब सेवा के लिए कुछ प्रकार के लोड परीक्षण कर रहा हूं। कभी-कभी यह क्लाइंट से "रिकॉर्ड मौजूद नहीं है" लौटाता है। मैं इस मुद्दे को पुन: पेश करना चाहता हूं। फ़ाइल को बंद करने और खोलने के लिए मुझे कोड को कहां संशोधित करना चाहिए। क्या आप कृपया मेरे साथ साझा कर सकते हैं? –

+0

खैर, मुझे यकीन नहीं है कि आप फ़ाइलों को कैसे प्रबंधित कर रहे हैं (मैं सी # के लिए नया हूं, मैं वीबी पृष्ठभूमि से हूं) लेकिन मैं आमतौर पर स्ट्रीमवाइटर/स्ट्रीम्रेडर्स (जो सी # में भी हैं) का उपयोग करता हूं। स्ट्रीमवाइटर अपनी कन्स्ट्रक्टर विधि के साथ फ़ाइल खोलते हैं, और फिर इसे बंद करने के लिए इसे तब तक खोलने के लिए खोलें जब तक कि करीबी विधि न कहें। तो हर बार जब आप किसी फ़ाइल में कुछ लिखना चाहते थे, तो आप कन्स्ट्रक्टर, लेखन विधि, फिर बंद करने की विधि कर सकते थे। जैसा कि मैंने पहले कहा था, बिना यह जानने के कि आप क्या हासिल करना चाहते हैं, मैं चीजों की सिफारिश नहीं कर सकता आप। क्या आप किसी कारण से फ़ाइल को लगातार अद्यतन करने का प्रयास कर रहे हैं? (उदाहरण के लिए एक गेम) – Pharap

+0

मैं एक webservice पर बार-बार हिट कर रहा हूं जहां कभी-कभी यह हमारे क्लाइंट से "रिकॉर्ड मौजूद नहीं है" फेंकता है। मैं इस मुद्दे को असीमित रूप से अपने अंत से पुन: पेश करना चाहता हूं। vb.net भी मेरे साथ ठीक है। यह वेब विधि कॉल के लिए कुछ प्रकार का लोड परीक्षण है। विधि को बार-बार और असीमित रूप से कॉल करना मैं प्राप्त करना चाहता हूं। –

3

फ़ाइल में एसिंक लेखन को संभालने के लिए एक सहायक विधि का उदाहरण।

public async Task FileWriteAsync(string filePath, string messaage, bool append = true) 
    { 
     using (FileStream stream = new FileStream(filePath, append ? FileMode.Append : FileMode.Create, FileAccess.Write, FileShare.None, 4096, true)) 
     using (StreamWriter sw = new StreamWriter(stream)) 
     { 
      await sw.WriteLineAsync(messaage); 
     } 
    } 
संबंधित मुद्दे