locked
how to create tasks to write file in same time for logging

    Question

  • i want to  write log message in file, in many case,should create many tasks to write in same time, by appending text into the file using FileIO.AppendTextAsync. 

    but when i do, error has occurred , Exception:HRESULT:0x80070005,saying the file is opened by othen thread,can't access.

    void CLOG::Open(String^ fileName)
    {
    	ifExit=false;
    	auto CreateFolderFN = KnownFolders::DocumentsLibrary->CreateFolderAsync("MCloudWin8",CreationCollisionOption::OpenIfExists);
    	task<StorageFolder^>(CreateFolderFN).then
    	([fileName,this](StorageFolder^ MCloudLogFolder)
    	{
    		testStr="";
    		FinishCreateFileDo+=ref new FinishCreateFileHandler(this,&CLOG::FinishCreateFileRespone);
    		auto calendar = ref new Windows::Globalization::Calendar();
    		String^ buf= fileName+calendar->YearAsString()+calendar->MonthAsNumericString()
    			+calendar->DayAsString()+".log";
    		return MCloudLogFolder->CreateFileAsync(buf, CreationCollisionOption::OpenIfExists);
    	}).then([this](StorageFile^file)
    	{
    		m_LogFile=file;
    		ifExit=true;
    		FinishCreateFileDo();
    	}).then([](task<void> t)
    	{
    		try
    		{
    			t.get();
    		}
    		catch(Platform::Exception^ e)
    		{
    			OutputDebugString(e->Message->ToString()->Data());
    		}
    
    	},task_continuation_context::use_arbitrary());
    }
    void CLOG::LogOut(Platform::String^ strToWrite)
    {
    
    	task<String^>([strToWrite](){
    		auto calendar = ref new Windows::Globalization::Calendar();
    		String^buf= calendar->YearAsString()+"-"+calendar->MonthAsNumericString()+"-"+calendar->DayAsString()
    		+" "+calendar->HourAsString()+":"+calendar->MinuteAsString()
    		+":"+calendar->SecondAsString()+":"+calendar->NanosecondAsString()+
    		strToWrite+"\r\n";
    		return buf;
    	}).then([this,strToWrite](String^ buf)
    	{
    		
    		if(ifExit==true)
    		{
    			//return FileIO::AppendTextAsync(m_LogFile, buf);	
    			create_task(FileIO::AppendTextAsync(m_LogFile, buf)).then([buf,this](task<void> t)
    			{
    				try
    				{
    					t.get();
    				}
    				catch(Platform::Exception^ e)
    				{
    					OutputDebugString(e->Message->ToString()->Data());
    				}
    			});
    		}
    		else
    		{
    			strBuf=strBuf+buf;
    		}
    	}).then([this,strToWrite](task<void> t)
    	{
    		try
    		{
    			t.get();
    		}
    		catch(Platform::Exception^ e)
    		{
    			OutputDebugString(e->Message->ToString()->Data());
    			//strBuf+=strToWrite;
    		}
    
    	},task_continuation_context::use_arbitrary());
    	
    	//Windows::Storage::FileIO::WriteTextAsync(m_LogFile, strToWrite)
    }

    void CLOG::FinishCreateFileRespone()
    {
    	task<void>
    	(
    		FileIO::AppendTextAsync(m_LogFile, strBuf)
    	).then([this]()
    	{
    		strBuf="";
    	}).then([](task<void> t)
    	{
    		try
    		{
    			t.get();
    		}
    		catch (Exception^e)
    		{
    			OutputDebugString(e->Message->ToString()->Data());
    		}
    	},task_continuation_context::use_arbitrary());
    }

    MainPage::MainPage()
    {
    	InitializeComponent();
    	CLOG::instance->Open("MCloudLog");
    	int a=170;
    	String ^p="a";
    	while (a)
    	{
    		a--;
    		p+="b";
    		//test(p);
    		CLOG::instance->LogOut("testTTT"+p);
    		wait(0.1);//if I wait(1) is OK,but less than 1 Exception arise.and interval time to log in my Program always less than 1ms, to loging in any time
    		CLOG::instance->LogOut("testTTT"+p);
    		wait(0.1);
    		CLOG::instance->LogOut("testTTT"+p);
    		wait(0.1);
    
    	}
    }


    Saturday, November 9, 2013 9:24 AM

All replies

  • i really can not  find any methods to close the file ,check if the file is be using ,and how can i make a lock? being crazy,  can anyone help me ???thanksssssssssss!
    Saturday, November 9, 2013 9:27 AM
  • Hi pingglala,

    Sorry for slowly response. Are you going to avoid the exception? If so, please handle this exception with try and catch.

    Also, you could do like this:

    if( open the file)

         false: it represents that another task is using this file

         success: You could handle this file.

    There is no lock for it.

    Hope it is helpful!

    Regards!


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Friday, November 15, 2013 8:51 AM
    Moderator
  • thanks Xiaoliang Chen very much.

    in then i cathch the error :The process cannot access the file because it is being used by another process。 And i Search this Exception Message in forum too,now i also trying to  lock it but fail; and can you say chinese

    Saturday, November 16, 2013 8:52 AM
  • Hi pingglala,

    Welcome here!

    There is no method for you to lock it, if you still want to do it like so, maybe you need to set a variable as mutex, it is simple that you just need set the flag as being successed when you successfully visit the file. After you use it, setting it as free will share a message that the file is free now.

    This is English forum, if you want to discuss this issue in chinese, you could ask this question on

    http://social.msdn.microsoft.com/Forums/zh-CN/home?forum=winstoreappzhcn

    Sorry for slowly response.

    Regards!


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Monday, November 18, 2013 7:52 AM
    Moderator
  • thans xiaoliang,

    i find the sample for logging in C#,http://code.msdn.microsoft.com/windowsapps/Logging-Sample-for-Windows-0b9dffd7  

    is that any method like that in C++?(await m_SemaphoreSlim.WaitAsync();) I use read_write_lock and critical_section are also failed....

    private async void WriteToFile(IEnumerable<string> lines)
            {
                await m_SemaphoreSlim.WaitAsync();
    
                await Task.Run(async () =>
                                         {
                                             try
                                             {
                                                 await FileIO.AppendLinesAsync(m_StorageFile, lines);
                                             }
                                             catch (Exception ex)
                                             {
                                                 // TODO:
                                             }
                                             finally
                                             {
                                                 m_SemaphoreSlim.Release();
                                             }
                                         });
            }
    

     

    Monday, November 18, 2013 9:46 AM
  • Hi pingglala,

    Welcome back!

       

    Yes, here is the method which is similiar with WaitAsync(), its namespace is System.Threading,Assembly:mscorlib (in mscorlib.dll).

    Return Value

    Type: System.Threading.Tasks::Task
    A task that will complete when the semaphore has been entered.

    This method is supported in 4.5 version, and supported in Win8.

    I have shown the link below:

     http://msdn.microsoft.com/en-us/library/hh462805

    Hope it is helpful for you!

    Regards!


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Tuesday, November 19, 2013 2:10 AM
    Moderator
  • in C++,I can't find this namspace:

    using namespace System::Threading  (error)

    using namespace System( error)

    Tuesday, November 19, 2013 3:58 AM
  • Hi pingglala,

    Welcome back!

    You must use this on C++/CLI, and then you could use this as below:

    #using<System.dll>
    using namespace System::Threading;

    Then you could use

    System::Threading::Semaphore class, the method WaitAsync is in this class


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Tuesday, November 19, 2013 8:29 AM
    Moderator
  • thanks xiaoliang,

    i use this

    #using<System.dll>
    using namespace System::Threading;

    but turn out error:

    error C1114: “c:\windows\microsoft.net\framework\v4.0.30319\system.dll”: WinRT 不支持托管程序集使用 #using

    Wednesday, November 20, 2013 8:08 AM
  • The namespace you could only used in managed code.

    So please forgive me I forgot that you are using c++ develop a native metro app.

    If so, you couldn't use this namespace, because you couldn't use .NET on native code. You could use it on C++/CLI only.

    So, as I have mentioned before, there is no a method for you to wait for a thread to complete.

    Thanks for your understanding!

    Regards!


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Thursday, November 21, 2013 1:53 AM
    Moderator